当我使用 CORS 时,AngularJS $http 似乎没有正确响应

Posted

技术标签:

【中文标题】当我使用 CORS 时,AngularJS $http 似乎没有正确响应【英文标题】:AngularJS $http seems to not respond correctly when I am using CORS 【发布时间】:2015-03-10 13:15:11 【问题描述】:

我有一个 AngularJS 应用程序。它向另一台服务器发送数据请求,因此每次 $HTTP 调用都会发出一个 OPTIONS 请求。

当我与提琴手核对时,有两个电话。总是返回 200 OK 然后数据调用的选项。

但是,当我检查 $HTTP 时,它似乎收到了第一个请求(选项请求),而没有收到带有真实数据的第二个请求。

有人能指出我正确的方向吗?

以下是未正确响应的代码示例:

 .factory('isUsernameAvailable', function (appConstant, $q, $http) 
    return function (username) 
        var deferred = $q.defer();
        // if (!angular.isDefined(username) || username == null || username == "" || username.length < 6 ) return deferred.resolve();
        var url = appConstant.baseUrl + '/api/user/existsByName';
        $http(
            url: url,
            method: "PUT",
            data: 
                userName: username
            
        ).then(function (data) 
                // Found the user, therefore not unique.
                deferred.reject("User name is taken");
            , function (data) 
                // User not found, therefore unique!
                deferred.resolve();
            );
        return deferred.promise;
    
  )

我希望它根据是否找到用户名返回成功或失败。但在这种情况下,它总是以失败/错误的形式响应。

以下是提出的要求:

OPTIONS http://localhost:3048/api/user/existsByName HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Access-Control-Request-Method: PUT
Origin: http://localhost:2757
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Referer: http://localhost:2757/Auth/register
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

给予:

HTTP/1.1 200 OK
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:2757
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Headers: content-type
X-SourceFiles: =?UTF-8?B?QzpcR1xhYmlsaXRlc3Qtc2VydmVyXFdlYlJvbGVcYXBpXHVzZXJcZXhpc3RzQnlOYW1l?=
X-Powered-By: ASP.NET
Date: Mon, 12 Jan 2015 17:52:12 GMT
Content-Length: 0

然后:

PUT http://localhost:3048/api/user/existsByName HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Content-Length: 35
Accept: application/json, text/plain, */*
Origin: http://localhost:2757
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Authorization: null
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:2757/Auth/register
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

"userName":"abdddcdefgg@live.com"

给予:

HTTP/1.1 404 Not Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:2757
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Custom-Header
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcR1xhYmlsaXRlc3Qtc2VydmVyXFdlYlJvbGVcYXBpXHVzZXJcZXhpc3RzQnlOYW1l?=
X-Powered-By: ASP.NET
Date: Mon, 12 Jan 2015 17:52:12 GMT
Content-Length: 0

问题是即使第二个请求在我调试成功和错误函数时返回 200,它仍然会一直转到错误函数。

【问题讨论】:

第二个请求是在 Fiddler 中成功还是 CORS 配置有问题? 第二个请求成功。我刚刚尝试了这里的建议:***.com/questions/17756550/angularjs-cors-issues 现在我只看到选项请求,没有别的。然后,选项请求似乎是 $http 调用认为的响应,因此根本没有帮助。 您能发布发出 CORS 请求的代码吗? 你能上传一张带有 http 调用(尤其是标头)的屏幕截图吗? 我认为问题出在响应代码上。对于 OPTIONS 调用,您需要用 302 我认为 进行响应 - 这就是您所得到的吗? 【参考方案1】:

您应该使用 JSONP 进行跨域 JSON 调用。在此处查看文档:https://docs.angularjs.org/api/ng/service/$http#jsonp。此外,您的引荐页面和来自 OPTIONS 请求的响应必须设置适当的 CORS 标头,否则浏览器将拒绝在此处发送请求,这是我使用的标头设置。

Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Accept, x-csrf-token, origin
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*

要使用 PUT 请求调用 $http.jsonp,您需要设置如下配置

var config = 
 method: 'POST',
 data:  test: 'test' 
;

然后将其传递给 $http.jsonp 调用

 $http.jsonp('http://example.com', config);

这里有更多文档 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 和 http://en.wikipedia.org/wiki/JSONP

【讨论】:

仅供参考,最新版本的 Chrome 不支持 Access-Control-Allow-Origin 上的通配符。更多细节在这里:***.com/questions/19743396/… 哪个版本?我从来没有遇到过这个问题。规范也明确允许w3.org/TR/cors/… 我目前正在使用:39.0.2171.95(64 位)我必须编写一个 Servlet,它将源点拉到“允许”服务器列表中,如果找到,则将该域专门包含在“访问控制允许来源”。服务器是一个 Google Apps Engine java 实例,这会改变公式吗? (我没有使用登录)。 我看了但看不到它在哪里特别提到了关于 CORS 和 JSONP 的任何内容。你能再解释一下吗。例如,如何使用 JSONP 执行 PUT、POST、GET? 我在 OS X 上使用 39.0.2171.95(64 位),我刚刚测试了它,它可以工作。跨域和引用服务器是否都有 CORS 标头?

以上是关于当我使用 CORS 时,AngularJS $http 似乎没有正确响应的主要内容,如果未能解决你的问题,请参考以下文章

如果我使用 XMLhttprequest 调用 API,它可以正常工作。但是当我使用 angularjs (1.5.6) 时,我得到了 CORS 错误

如果我使用XMLhttprequest调用API,它可以正常工作。但是当我使用angularjs(1.5.6)时,我得到了CORS错误

AngularJS Spring Social Facebook CORS 问题

不允许使用 CORS 使用 angularjs 进行跨域请求的 DELETE 请求

AngularJS $http 对 Web 服务的请求需要 CORS

rails-api 和 angularJs 中的 CORS