CORS 预检返回 200,但随后的 PUT 从未发生(带有外部 REST API 的 Angular JS)

Posted

技术标签:

【中文标题】CORS 预检返回 200,但随后的 PUT 从未发生(带有外部 REST API 的 Angular JS)【英文标题】:CORS preflight returns 200 but subsequent PUT never happens (Angular JS with external REST API) 【发布时间】:2014-07-10 09:39:42 【问题描述】:

我正在使用一个与 REST api 对话的 Angular 应用

我已设置访问控制,以便我的 GET 请求按预期工作。 (浏览器发送一个预检 OPTIONS 请求,然后触发后续的 GET)。

但是,我的 PUT 遇到了问题。

问题是 PUT 选项预检似乎返回正常,但 PUT 永远不会触发。

首先我将展示什么是有效的,然后是什么是失败的。我正在使用 Charles 监视电话。


GET(工作)

1) 预检请求

OPTIONS /v1/account HTTP/1.1
Host    api.mysite.com
Access-Control-Request-Method   GET
Origin  http://127.0.0.1:9000
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/34.0.1847.137 Safari/537.36
Access-Control-Request-Headers  accept, authorization
Accept  */*
Referer http://127.0.0.1:9000/
Accept-Encoding gzip,deflate,sdch
Accept-Language en-US,en;q=0.8

2) 预检响应

HTTP/1.1 200 OK
Server  nginx/1.6.0
Date    Wed, 21 May 2014 15:43:25 GMT
Content-Type    application/octet-stream
Content-Length  0
Connection  keep-alive
Access-Control-Allow-Origin *
Access-Control-Allow-Methods    *
Access-Control-Allow-Headers    Origin, X-Requested-With, Content-Type, Accept, Authorization, WWW-Authenticate, X-BLURR-DEBUG
Access-Control-Allow-Credentials    true

3) GET 请求

GET /v1/account HTTP/1.1
Host    api.mysite.com
Accept  application/json, text/plain, */*
Origin  http://127.0.0.1:9000
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36
AUTHORIZATION   DFHD8D...
Referer http://127.0.0.1:9000/
Accept-Encoding gzip,deflate,sdch
Accept-Language en-US,en;q=0.8

4) GET 响应

 some json as expected 

PUT(不工作)

现在,这里的 PUT 似乎返回了正常的预检响应,但从未收到 PUT 请求:

1) 预检请求

OPTIONS /v1/account HTTP/1.1
Host    api.mysite.com
Access-Control-Request-Method   PUT
Origin  http://127.0.0.1:9000
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36
Access-Control-Request-Headers  accept, authorization, content-type
Accept  */*
Referer http://127.0.0.1:9000/
Accept-Encoding gzip,deflate,sdch
Accept-Language en-US,en;q=0.8

2) 预检响应

HTTP/1.1 200 OK
Server  nginx/1.6.0
Date    Wed, 21 May 2014 15:51:41 GMT
Content-Type    application/octet-stream
Content-Length  0
Connection  keep-alive
Access-Control-Allow-Origin *
Access-Control-Allow-Methods    *
Access-Control-Allow-Headers    Origin, X-Requested-With, Content-Type, Accept, Authorization, WWW-Authenticate, X-BLURR-DEBUG
Access-Control-Allow-Credentials    true

问题

PUT 的 preflight 响应似乎没问题,所以我不确定为什么浏览器从不发送 actual PUT 请求。

任何帮助或指导都会很棒!谢谢

【问题讨论】:

【参考方案1】:

*(星号)不是Access-Control-Allow-Methods 标头的有效值。您需要列出实际的方法(例如GET, PUT)。似乎虽然来自服务器的预检响应成功,但浏览器可能仍在拒绝预检而不发送实际请求。检查浏览器的控制台日志是否有任何错误。

【讨论】:

以上是关于CORS 预检返回 200,但随后的 PUT 从未发生(带有外部 REST API 的 Angular JS)的主要内容,如果未能解决你的问题,请参考以下文章

CORS 预检请求返回 HTTP 405

CORS:预检通过,主请求完成 w/200,但浏览器仍然有 Origin 错误

如何处理无效的 CORS 预检请求?

Asp.NET Core:对服务的跨域请求(预检)返回代码 204 而不是 200

VB.NET Web API CORS PUT 预检 405 错误

CORS 预检请求返回带有 Windows 身份验证的 HTTP 401