跨域资源共享的问题:预检请求后 OSX Safari 和 iOS Safari 均失败

Posted

技术标签:

【中文标题】跨域资源共享的问题:预检请求后 OSX Safari 和 iOS Safari 均失败【英文标题】:problems with Cross Origin Resource Sharing: both OSX Safari and iOS Safari fail after preflight request 【发布时间】:2017-04-10 02:30:25 【问题描述】:

最近我在 Safari(OSX 和 ios)上遇到了 CORS(跨源资源共享)请求的问题,而相同的请求在 Chrome 和 Firefox 上完美运行。我关注the documentation of W3C 并在服务器端处理预检请求,我的回复如下:

HTTP/1.0 200 OK
Access-Control-Allow-Origin: http://192.168.1.96:4399
Access-Control-Allow-Methods: POST
Access-Control-Allow-Methods: GET
Access-Control-Allow-Methods: OPTIONS
Access-Control-Allow-Headers: Origin
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Headers: Accept
Access-Control-Allow-Headers: Access-Control-Request-Method
Access-Control-Allow-Headers: Access-Control-Request-Headers
Access-Control-Allow-Headers: DNT
Access-Control-Allow-Headers: X-CustomHeader
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 0
Date: Fri, 25 Nov 2016 08:45:25 GMT
Origin: http://192.168.1.96:4399
Access-Control-Expose-Headers: Origin
Content-Encoding: gzip
Transfer-Encoding: chunked

这样的响应在 Chrome、Firefox 和 android 浏览器上运行良好:在预检请求之后立即发送 POST 请求。但是在 Safari 上,在服务器响应重新发送请求后,我从控制台收到了这样的错误消息:

Failed to load resource: The network connection was lost.

我检查了来自服务器的预检响应,但发现它与上面相同......经过多次搜索和尝试,我仍然无法使其工作:-( 有没有人遇到过这个问题?谁能弄清楚我犯了什么错误? 提前非常感谢!

【问题讨论】:

听起来你是 Safari 中的一个错误,你可以在 bugs.webkit.org 报告 @sideshowbarker 非常感谢。但有趣的是,当我从 OSX Safari 的开发菜单中检查“禁用跨域限制”选项时,我偶尔会发现它有效!我怀疑这个问题可能与浏览器安全策略有关,我会继续努力解决。 我认为当你禁用跨域限制时,你可以毫无问题地连接到目标服务器是很自然的,这一点也不有趣,因为浏览器故意使用跨域资源共享的限制来提高我们的安全性。所以,是的,这个问题绝对与浏览器有关。 【参考方案1】:

这都是关于 Safari 将 origin 添加到 OPTIONS 请求标头 Access-Control-Request-Headers

因此,要修复它,您应该在 Access-Control-Allow-Headers 中启用此标头作为响应。

PS:见类似问题CORS request not working in Safari

【讨论】:

OP 在网络级别看到预检请求失败完成。您指的是配置不正确的 OPTIONS 响应。但他一开始就没有得到那种回应。 @RavenHursT 不,brutto 提到了格式错误的请求标头,因此这是正确答案(我刚刚验证过,它对我有用)

以上是关于跨域资源共享的问题:预检请求后 OSX Safari 和 iOS Safari 均失败的主要内容,如果未能解决你的问题,请参考以下文章

自定义请求头引起预检请求

跨域资源共享错误:预检响应不允许标头

CORS 预检响应未成功

http跨域预检问题

为啥跨域 HEAD 请求需要预检?

为啥我的跨域 POST 请求预检了 OPTIONS 请求?