【问题标题】:jQuery Cross Domain RequestjQuery 跨域请求
【发布时间】:2014-09-01 08:19:51
【问题描述】:

我正在尝试让跨域请求正常工作。相关代码如下:

var promise = $.ajax({
    type: 'GET',
    url: registerUrl,
    dataType: 'json',
    cache: false,
    crossDomain: true,
    xhrFields: { withCredentials: true },
    contentType: 'application/json'
});

我控制调用和接收服务器,这是我得到的响应:

原始请求(由 Fiddler 提供):

OPTIONS http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405022169353 HTTP/1.1
Host: localhost:5080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:53054
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive

原始响应:

HTTP/1.1 200 OK
Date: Thu, 10 Jul 2014 19:56:11 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Content-Length: 0
Server: Jetty(8.1.4.v20120524)

现在,我的理解是,此预检的 Allow-Origin: * 应该足以让 Firefox / Chrome 继续请求。奇怪的是,IE 没有对此请求进行预检,并且它可以工作(尽管抛出了一个警告,表明它不遵循 CORS 规范)。

我在这里遗漏了什么吗?我已经尝试在我能想到的 ajax 请求上设置每个值,并且服务器看起来正在响应 OPTIONS 请求的适当响应。

来自firefox的具体错误信息:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405022169353. This can be fixed by moving the resource to the same domain or enabling CORS.

我做错了什么?可以改变什么来解决这个问题?

编辑:新的请求/响应字段:

OPTIONS http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405026511996 HTTP/1.1
Host: localhost:5080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:53054
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive

回复:

HTTP/1.1 200 OK
Date: Thu, 10 Jul 2014 21:08:38 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Credentials: true
Content-Length: 0
Server: Jetty(8.1.4.v20120524)

现在,fiddler 也记录了实际的请求:

GET http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405026511996 HTTP/1.1
Host: localhost:5080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Referer: http://localhost:53054/
Origin: http://localhost:53054
Connection: keep-alive

然后回应:

HTTP/1.1 200 OK
Date: Thu, 10 Jul 2014 21:08:38 GMT
Content-Type: application/json;charset=ISO-8859-1
Content-Length: 175
Server: Jetty(8.1.4.v20120524)

{"status":true,"host":"<myServerName>","port":1935,"liveHost":"<myServerName>","livePort":5080,"gsid":"abcde","connCount":2,"maxConns":25000,"version":"1.0"}

但是,firefox 似乎阻止了请求,因此 ajax 调用总是命中我的失败处理程序。这看起来很奇怪......

【问题讨论】:

  • 这个post 也很有用;阅读与 CORS 请求相关的部分。
  • 我使用的是 1.5.2 之后的版本,请求中没有发送 x-requested-with 标头。是回复中没有Access-Control-Allow-Headers的问题吗?

标签: javascript jquery ajax cross-domain chat


【解决方案1】:

您的请求似乎正在请求发送内容类型请求标头的权限,并且它需要发送凭据的权限。

据我所知,您的请求标头似乎是正确的。但是,您的响应应该包含另外两个标题:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type

这是来自我工作过的另一个网站的预检请求示例,以及预检响应:

这是预检选项请求标头

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, applicationname
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Cookie:*sanitized cookie data*
Host:sanitized.domain.com
Origin:https://sanitized.domain.com
Pragma:no-cache
Referer:https://sanitized.domain.com/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36

接下来是预检响应标头:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:applicationname
Access-Control-Allow-Origin:https://sanitized.domain.com
Cache-Control:no-cache
Connection:keep-alive
Content-Length:0
Date:Thu, 10 Jul 2014 20:19:25 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

注意添加了 Access-Control-Allow-Credentials 和 Access-Control-Allow-Headers 标头。另请注意,我的请求在 Access-Control-Request-Headers 标头中发送了“接受”,并且响应不包含“接受”。这是因为“接受”被视为此处定义的简单标头:http://www.w3.org/TR/cors/#simple-header。此外,仅当 content-type 的值为以下之一时,它才有资格作为简单标头:

  • 文本/纯文本
  • 多部分/表单数据
  • application/x-www-form-urlencoded

在您的情况下,由于内容类型是 application/json,因此您需要一个包含“content-type”的响应标头,如上所示。

更新: 在预检请求之后发生的请求和响应应包含相同的 CORS 标头,以防止浏览器拒绝请求和/或响应。您至少希望响应包含 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 标头。

【讨论】:

  • 我明白了。让我尝试删除内容类型标头或添加接受标头动词,看看是否有效...
  • 好的,现在响应返回Access-Control-Allow-Headers: content-type,但 Firefox 似乎仍在拒绝该请求。
  • 您还需要使用允许凭据标头进行响应:Access-Control-Allow-Credentials:true
  • 响应包含:Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: content-type Access-Control-Allow-Credentials: true - 仍然没有运气。
  • 已更新。看起来跨域调用现在工作正常,但 Firefox 一直在处理回调。失败处理程序的 jQuery 参数:{object}、{'error'}、{''}
【解决方案2】:

尝试设置

dataType:'html' 

(Where is the correct place to enable CORS?)

【讨论】:

  • 这不起作用。指定 HTML 只会更改响应值,让我手动将 IE 中的响应转换为 Json,Firefox 仍然报告无法进行跨域请求。还有其他潜在的想法吗?在这一点上,我正在撕扯我的头发。
猜你喜欢
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
  • 2012-03-18
  • 2014-04-16
相关资源
最近更新 更多