2

我正在开发一个 AngularJS 项目,我需要执行跨域 (CORS) POST。我花了(很长)一段时间才让它工作,好吧,它现在有点工作:

  • 飞行前(OPTIONS)请求发送正确,我的服务器也正确响应。
  • 实际的 POST 请求也正确发送,我的服务器正常接收,并返回 201(已创建)响应。

那么问题是什么?

那么Angular $http 对象不会转到“成功”回调,而是转到“错误”回调......状态代码为0并且没有特定错误。所以从我的页面上,我无法知道我的请求是否真的有效。我知道它确实有效的唯一方法是控制(调试)服务器并使用 Fiddler。

以前有人遇到过这个问题吗?有一个可行的解决方案但不能说它确实有效,这有点令人沮丧:)

这是我的 $http 请求:

this.simulate = function (url, content) {
var deferred = $q.defer();

var data = { "Data": content, "Timestamp": new Date() };

$http.defaults.useXDomain = true;
$http.post(url, data)
    .then(function(response) {
        deferred.resolve({
            isSuccess: true,
            httpCode: response.status,
            errorMessage: "",
            url: url,
            data:data
        });
    },function(response) { // This is this error callback that is being called, despite the fact that my request is working fine...
        deferred.resolve({
            isSuccess: false,
            httpCode: response.status,
            errorMessage: response.data.Message + " " + response.data.ExceptionMessage,
            url: url,
            data: data
        });
    });

return deferred.promise;
};

在提琴手中,这就是我得到的:

飞行前请求:

OPTIONS http://myServer:82/xclient/event/volupdate HTTP/1.1
Host: myServer:82
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://myClient:1855
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-requested-with, authorization, ssotoken, content-type
Accept: */*
DNT: 1
Referer: http://myClient:1855/XClient/testharness/eventing
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6,fr-FR;q=0.4

这给了我飞行前的反应:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://myClient:1855
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: accept, origin, x-requested-with, authorization, ssotoken, content-type
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 07 Aug 2013 10:13:05 GMT
Content-Length: 0

然后是实际的 POST 请求:

POST http://myServer:82/xclient/event/volupdate HTTP/1.1
Host: myServer:82
Connection: keep-alive
Content-Length: 56
Origin: http://myClient:1855
Authorization: SSOB2L1ax<BLAHBLAHBLAH>EP49w=|0|jaussan|System X|20130825131712|1748001|
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept: application/json, text/plain, */*
X-Requested-With: XMLHttpRequest
DNT: 1
Referer: http://myClient:1855/XClient/testharness/eventing
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6,fr-FR;q=0.4

{"Data":"SomeData","Timestamp":"2013-08-07T10:13:06.533Z"}

然后是对 POST 的正常 201 创建响应:

HTTP/1.1 201 Created
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 07 Aug 2013 10:13:05 GMT
Content-Length: 0

如您所见,一切似乎都很正常,但 $http 似乎认为不是。

以下是 Firebug 的一些屏幕截图:

$http 转到错误的回调: $http 转到错误的回调

这是我从 $http 得到的响应......不是我的 201!: 这是我从 $http 得到的响应......不是我的 201!

4

1 回答 1

4

看起来好像您的服务器正在正确处理 OPTIONS(预检)请求,但不是实际的 POST 请求。您的服务器至少需要在对您的 POST 请求的响应中包含一个 Access-Control-Allow-Origin 标头。在你的情况下,那将是:Access-Control-Allow-Origin: http://myClient:1855

为了将来参考,有一篇关于 CORS 的优秀文章,每个必须支持跨域环境的人都绝对应该收藏:MDN on HTTP access control

于 2013-08-08T14:12:31.450 回答