【问题标题】:AngularJS $http seems to not respond correctly when I am using CORS当我使用 CORS 时,AngularJS $http 似乎没有正确响应
【发布时间】: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 配置有问题?
  • 第二个请求成功。我刚刚尝试了这里的建议:stackoverflow.com/questions/17756550/angularjs-cors-issues 现在我只看到选项请求,没有别的。然后,选项请求似乎是 $http 调用认为的响应,因此根本没有帮助。
  • 您能发布发出 CORS 请求的代码吗?
  • 你能上传一张带有 http 调用(尤其是标头)的屏幕截图吗?
  • 我认为问题出在响应代码上。对于 OPTIONS 调用,您需要用 302 我认为 进行响应 - 这就是您所得到的吗?

标签: angularjs


【解决方案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_CORShttp://en.wikipedia.org/wiki/JSONP

【讨论】:

  • 仅供参考,最新版本的 Chrome 不支持 Access-Control-Allow-Origin 上的通配符。更多细节在这里:stackoverflow.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 标头?
猜你喜欢
  • 2013-10-23
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 2010-09-08
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多