+-

在调试CORS问题时,我遇到了我发现了以下行为. Chrome会发出以下OPTIONS预检请求(由Chrome本身在CURL中重写):
curl -v 'https://www.example.com/api/v1/users' -X OPTIONS -H 'Access-Control-Request-Method: POST' -H 'Origin: http://example.com' -H 'Accept-Encoding: gzip,deflate,sdch' -H 'Accept-Language: es-ES,es;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://example.com/users/new' -H 'Connection: keep-alive' -H 'Access-Control-Request-Headers: accept, x-api-key, content-type'
如果以下情况,服务器对此请求的响应:
< HTTP/1.1 403 Forbidden
< Date: Thu, 21 Jul 2016 14:16:56 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< X-Frame-Options: SAMEORIGIN
< Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
< Content-Length: 20
< Keep-Alive: timeout=5, max=100
< Connection: Keep-Alive
作为响应的主体’无效的CORS请求’.如果我重复请求删除标题’Access-Control-Request-Method'(并且只有那个标题),则OPTIONS请求成功并返回以下响应:
< HTTP/1.1 200 OK
< Date: Thu, 21 Jul 2016 14:21:27 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< X-Frame-Options: SAMEORIGIN
< Access-Control-Allow-Headers: origin, content-type, accept, x-requested-with, x-api-key
< Access-Control-Max-Age: 60
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
< Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
< Content-Length: 0
< Keep-Alive: timeout=5, max=100
< Connection: Keep-Alive
但是,违规标题是CORS spec standard header,所以它不应该阻止请求成功,对吧?为什么这个标题导致了这种行为?
我如何调整服务器发送的访问控制标头,以便在使用Chrome时使请求生效?
顺便说一下,我使用的是Chrome 36.0,服务器使用的是Spring Boot,其中CORS标头由Spring管理.
当Firefox(v47.0)发出请求时,行为会有所不同,但会产生模拟结果. Firefox甚至不发送预检请求,它直接发送POST请求,作为响应接收403 Forbidden.但是,如果我使用’Copy as cURL’选项复制请求,并从终端窗口重复它,它会成功并在响应中发送正确的CORS头.
任何想法?
更新:Firefox会发送预检OPTIONS请求(如Live HTTP标头插件所示),但Firebug会屏蔽它,因此两个浏览器中的行为完全相同.在两种浏览器中,“访问控制请求方法”标题是使请求失败的区别.
最佳答案
经过大量的挣扎,我终于找到了问题所在.我在Spring中配置了一个请求映射来处理OPTIONS流量,如下所示:
@RequestMapping(value= "/api/**", method=RequestMethod.OPTIONS)
public void corsHeaders(HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
response.addHeader("Access-Control-Max-Age", "3600");
}
我不知道默认情况下Spring使用default CORS processor,而且它似乎干扰了我的请求映射.删除我的请求映射并将@CrossOrigin批注添加到适当的请求映射解决了该问题.
点击查看更多相关文章
转载注明原文:spring – 由于标准头文件,CORS预检请求失败 - 乐贴网