我正在使用RESTful API为某些服务编写Web应用程序。该API位于https://api.example,应用位于https://app.example。使用CORS的简单GET请求在Chrome和Firefox中运行良好。某些方法通过POST接受数据,并在Location头中使用新的uri返回303代码。
预检OPTIONS请求很好:
Request Method:OPTIONS
Status Code:200 OK
请求标题
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
响应标头
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
然后实际请求在收到303后停止:
Request URL:https://api.example
Request Method:POST
Status Code:HTTP/1.1 303 See Other
回复标题:
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
RFC用户代理应遵循重定向,但Chrome和FF似乎没有按预期运行。这是浏览器的错误还是我做错了什么?
更新:如果我使用--disable-web-security启动chrome,一切正常。
答案 0 :(得分:15)
我也一直在努力解决这个问题。看来,规范禁止对预先发出的CORS请求进行3xx重定向。
来自规范:
(步骤1和2.详细说明了印前检查过程。我们步骤......)
... 3。这是实际请求。应用make a request步骤并观察 在发出请求时,请求规则。
如果响应的HTTP状态代码为301,302,303,307或308 应用cache and network error steps。
然后我们向下滚动到http://www.w3.org/TR/cors/#cache-and-network-error-steps:
每当应用网络错误步骤时,请终止算法 调用这组步骤并设置跨源请求状态 网络错误。
注意:这对设置用户凭据没有影响。即如果阻止 如果未设置cookies标记,则响应将设置Cookie。
每当应用缓存和网络错误步骤时,请按照以下步骤操作 步骤进行:
删除预检结果缓存中origin项字段的条目 value是源origin和url字段值的区分大小写的匹配项 是一个区分大小写的请求URL匹配。
应用网络错误步骤,就像调用的算法一样 缓存和网络错误步骤调用了网络错误步骤 代替。
(重点来自文档。)
但是,对于简单的CORS请求,允许使用3xx重定向。答案 1 :(得分:1)
如果这里的铬虫是由铬支持给你的代码可能出现的错误:
如果同源请求导致重定向到不同的来源,则
不强制执行重定向响应的访问控制检查
本身,因为导致重定向的请求是
同源。
如果同源请求导致重定向到不同的来源,则 使用原始请求的URL作为新的来源 请求不使用唯一的安全来源。
跟踪客户端(即XMLHttpRequest)是否实际请求了 凭证首先发送。当一个 同源请求重定向到原始的不同来源 请求将发送cookie,无论是否请求,因为它是 同源。新的跨源请求不应发送cookie 除非他们被请求,否则访问控制检查 如果服务器被授予,响应将成功 “访问控制允许来源= *”。