简体   繁体   English

来自Safari中Express服务器的响应数据中的HTTP标头

[英]HTTP headers in response data from Express server in Safari

My angular app is making a call to my API from a ui-router resolve: 我的角度应用程序正在通过ui路由器解析来调用我的API:

...
$stateProvider
    .state('gallery',{
        abstract: true, 
        templateUrl: 'components/gallery/gallery.html'
    })
    .state('gallery.views', {
        url: "/{gallery:shades-of-gray|color}",
        views: {
            'left@gallery': {
                templateUrl: 'components/gallery/partials/gallery-slider.html',
                controller: 'SliderController'
            },
            'right@gallery': {
                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只需进行API调用即可解决诺言:

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: 在Safari中,我等待120秒等待$http承诺解决,这时我会看到带有正确状态代码,标头等的响应。但是(与Chrome中的Firefox不同), response.data是包含HTTP标头的字符串:

在此处输入图片说明

I can't parse it reliably (because I'll have an Authorization header with some responses). 我无法可靠地解析它(因为我将获得带有一些响应的Authorization标头)。 What gives? 是什么赋予了? Why is this a problem on Safari and what can I do about it? 为什么在Safari上这是个问题,我该怎么办?

If it helps, here is the Express code that responds to the request: 如果有帮助,这里是响应请求的Express代码:

...
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. 其中drawings只是JSON对象的数组。 Thanks. 谢谢。

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: 在Safari中,我等待120秒等待$ http承诺解决,这时我会看到带有正确状态代码,标头等的响应。但是(与Chrome中的Firefox不同), response.data是包含HTTP标头的字符串:

HTTP/1.1 OK unknown

-> This is not a valid HTTP response header . ->这不是有效的HTTP响应标头

6.1 Status-Line 6.1状态栏

The first line of a Response message is the Status-Line, consisting of the protocol version followed by a numeric status code and its associated textual phrase, with each element separated by SP characters. 响应消息的第一行是状态行,由协议版本,数字状态代码及其关联的文本短语组成,每个元素由SP字符分隔。 No CR or LF is allowed except in the final CRLF sequence. 除最后的CRLF序列外,不允许CR或LF。

  Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF 

Should be: 应该:

HTTP/1.1 200 OK

Maybe Safari does not accept this as a header and pushes the header data towards the response? 也许Safari不接受此作为标头并将标头数据推向响应? Or do you receive other headers before this? 还是在此之前收到其他标题?

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) . 真正可以简化为res.json(ret)

From the Express docs for res.sendStatus() : Express文档中获取res.sendStatus()

Set the response HTTP status code to statusCode and send its string representation as the response body. 将响应HTTP状态代码设置为statusCode并发送其字符串表示形式作为响应主体。

Contrast this with res.status() : 将此与res.status()对比:

Use this method to set the HTTP status for the response. 使用此方法设置响应的HTTP状态。

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. 但是,Firefox和Chrome浏览器使我无法完全确定,但我当然很高兴Safari引起了我的注意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM