为什么浏览器不遵循使用XMLHTTPRequest和CORS的重定向?

gal*_*dog 12 javascript ajax rest google-chrome cors

我正在使用RESTful API为某些服务编写Web应用程序.该API可通过https://api.example和app https://app.example获取.使用CORS的简单GET请求在Chrome和Firefox中运行良好.某些方法通过POST接受数据,并在Location头中使用新的uri返回303代码.

预检OPTIONS请求很好:

Request Method:OPTIONS
Status Code:200 OK
Run Code Online (Sandbox Code Playgroud)

请求标题

Accept:*/*
Accept-Charset:UTF-8,*;q=0.5
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,ru;q=0.6
Access-Control-Request-Headers:origin, authorization, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:api.example
Origin:https://app.example
Referer:https://app.example/app/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.32 (KHTML, like Gecko) Chrome/27.0.1425.0 Safari/537.32 SUSE/27.0.1425.0
Run Code Online (Sandbox Code Playgroud)

响应标题

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Authorization, Content-Type
Access-Control-Allow-Methods:GET,POST,PUT,DELETE,HEAD,OPTIONS
Access-Control-Allow-Origin:https://app.example
Access-Control-Expose-Headers:*
Access-Control-Max-Age:3628800
Connection:keep-alive
Content-Length:0
Date:Sun, 05 May 2013 15:22:50 GMT
Server:nginx/1.2.5
Run Code Online (Sandbox Code Playgroud)

然后实际请求在收到303之后才停止:

Request URL:https://api.example
Request Method:POST
Status Code:HTTP/1.1 303 See Other
Run Code Online (Sandbox Code Playgroud)

响应标头:

Server:nginx/1.2.5
Location:https://api.example/some_url
Date:Sun, 05 May 2013 15:27:49 GMT
Content-Type:application/json
Content-Length:0
Connection:keep-alive
Access-Control-Max-Age:3628800
Access-Control-Expose-Headers:*
Access-Control-Allow-Origin:https://app.example
Access-Control-Allow-Methods:GET,POST,PUT,DELETE,HEAD,OPTIONS
Access-Control-Allow-Headers:Authorization, Content-Type
Access-Control-Allow-Credentials:true
Run Code Online (Sandbox Code Playgroud)

RFC用户代理应该遵循重定向,但Chrome和FF似乎没有按预期运行.这是浏览器的错误还是我做错了什么?

更新:如果我用--disable-web-security启动chrome,一切正常.

not*_*you 15

我也一直在努力解决这个问题.看来,规范禁止对预先发出的CORS请求进行3xx重定向.

http://www.w3.org/TR/cors/

从规格:

(步骤1和2.详细说明了预检过程.我们来了......)

... 3.这是实际的要求.在发出请求时,应用make a request步骤并遵守下面的请求规则.

如果响应的HTTP状态代码为301,302,303,307或308,则 应用缓存和网络错误步骤.

然后,如果我们向下滚动到http://www.w3.org/TR/cors/#cache-and-network-error-steps:

每当应用网络错误步骤时,终止调用此组步骤的算法并将跨源请求状态设置为网络错误.

注意:这对设置用户凭据没有影响.即如果未设置阻止cookie标志,则响应将设置cookie.

每当应用缓存和网络错误步骤时,请按照下列步骤操作:

删除预检结果缓存中的条目,其中origin字段值是源origin的区分大小写的匹配项,url字段值是对请求URL的区分大小写的匹配项.

应用网络错误步骤,就好像调用缓存的算法和网络错误步骤调用网络错误步骤一样.

(重点来自文件.)

但是,允许3xx重定向用于简单的CORS请求.


Joã*_*rão 2

如果这是 chromium bug,那么 chromium 支持可能会出现代码错误:

  1. 如果同源请求导致重定向到不同的源,则
    不要对重定向响应
    本身强制执行访问控制检查,因为导致重定向的请求是
    同源的。

  2. 如果同源请求导致重定向到不同的源,
    请使用原始请求的 URL 作为新请求的源,不要使用唯一的安全源。

  3. 跟踪客户端(即 XMLHttpRequest)是否确实
    首先请求发送凭据。当同源请求重定向到异源时,无论原始请求是否请求,都会发送cookie,因为它是同源的。新的跨域请求不应发送 cookie,除非有请求,这样,如果服务器授予“Access-Control-Allow-Origin=*”,则对响应的访问控制检查将会成功。