Ad

HTTP Headers In Response Data From Express Server In Safari

- 1 answer

My angular app is making a call to my API from a ui-router resolve:

...
$stateProvider
    .state('gallery',{
        abstract: true, 
        templateUrl: 'components/gallery/gallery.html'
    })
    .state('gallery.views', {
        url: "/{gallery:shades-of-gray|color}",
        views: {
            '[email protected]': {
                templateUrl: 'components/gallery/partials/gallery-slider.html',
                controller: 'SliderController'
            },
            '[email protected]': {
                templateUrl: 'components/gallery/partials/gallery-img.html',
                controller: 'GalleryImgController'
            }
        },
        resolve: {
            apiFactory: 'apiFactory',
            drawings: function(apiFactory, $stateParams){
                var param = $stateParams.gallery === 'color' ? 'color' : 'bw';
                return apiFactory.getImageUrls(param);
            }
        }
    });
...

My ApiFactory simply makes an API call and resolves the promise:

apiFactory.getImageUrls = function(gallery){
    if (gallery === undefined)
        var gallery = 'all';

    return $http({
        method: 'GET',
        url: API_URL + '/drawings/' + gallery,
    }).then(function(response){
        return response.data.gallery;
    });
};

And my two controllers use the data injected by my resolve:

.controller('SliderController', function($scope, drawings){
    $scope.drawings = drawings;
    ...
}
controller('GalleryImgController', function($scope, drawings){
   $scope.currentDrawing = drawings[0];
   ...
}

In Safari, I wait 120 seconds for the $http promise to resolve, at which point I see my response with proper status code, headers etc. However (unlike Firefox in Chrome), response.data is a string containing the HTTP headers:

enter image description here

I can't parse it reliably (because I'll have an Authorization header with some responses). What gives? Why is this a problem on Safari and what can I do about it?

If it helps, here is the Express code that responds to the request:

...
getDrawingSet(gallery, (err, drawings) => {
    if (err)
        return next(err);
    let ret = {};
    ret["gallery"] = drawings;
    res.status(httpStatus[200]).json(ret);
});
...

Where drawings is just an array of JSON objects. Thanks.

Ad

Answer

Solution

The issue was on the server (obviously).

I simply changed the following line from:

res.sendStatus(200).json(ret);

to

res.status(200).json(ret);

Which can really be simplified to res.json(ret).

From the Express docs for res.sendStatus():

Set the response HTTP status code to statusCode and send its string representation as the response body.

Contrast this with res.status():

Use this method to set the HTTP status for the response.

I thought I was doing the latter with the former. However Firefox and Chrome allowed me to get away with this I'm not entirely sure, but I'm certainly happy that Safari brought this error to my attention.

Ad
source: stackoverflow.com
Ad