Safari拒绝一些涉及重定向的CORS请求,声称不允许使用某些标头。但是这个标题从未被脚本请求,但是由浏览器添加,所以我认为它应该没关系。
我观察到Safari似乎比其他浏览器更严格地解释CORS协议的情况。它使用错误消息拒绝某些请求
[错误] 无法加载资源:
Access-Control-Allow-Headers
不允许使用请求标题字段....
我已经在标题字段Accept-Encoding
中看到了这一点,在将该字段添加到Access-Control-Allow-Headers
后,DNT
重复了同样的错误。预检请求的Access-Control-Request-Headers
列表中包含的其他字段为Cache-Control
,Origin
和Accept-Language
。
据我所知,这只会影响重定向的请求。如果我设法立即命名最终位置,请求成功。
我在自己的代码中创建了XMLHttpRequest
,没有任何库或框架干扰它。我绝对肯定我从未调用setRequestHeader()
方法。
在WHATWG XHR spec之后我会假设我的author request headers列表应为空。 Request部分声明:
我可以在文档中看到send()
的非空参数可能会触发Content-Type
作为作者请求标题,但即使有这样的无参数调用,我也遇到了问题
W3C CORS recommendation将the Access-Control-Request-Headers
field描述为由作者请求标题组成:
如果author request headers不为空,则包含带有标题字段值的
Access-Control-Request-Headers
标头,以字典顺序排列author request headers的标题字段名称的逗号分隔列表,每个{{3} (即使一个或多个是converted to ASCII lowercase)。
根据该规范,我可以看到错误的可能原因是:
如果simple header中每个标题的字段名称与标题中的某个标题字段名称不匹配author request headers且标题不是{{3 },应用ASCII case-insensitive。
或许W3C CORS建议是错误的地方。也许它已被simple header取代了?这写在关于cache and network error steps
的部分
让标题成为请求的WHATWG Fetch living standard CORS-preflight fetch' s {{3} },不包括names和重复项,按字典顺序排序,以及header list。
让 value 成为标题中的项目,彼此相隔0x2C。
headers CORS-safelisted request-headers到预检中的值 ' byte-lowercased。
< / LI> 醇>
那么这里的标题列表是什么? Set和Access-Control-Request-Headers
的生活标准之间的联系似乎是header list。
- 醇>
让 req 成为新的XHR,初始化如下:
因此它将作者请求标题(根据我上面的考虑因素应该为空)绑定到标题列表,该标题列表用于构建所请求标题的列表。至少最初。
当然,Fetch规范很长,并在许多位置提到术语“标题列表”。很可能在那里某处有一些条款要求添加某些标题字段。但是,我发现Accept-Encoding
或DNT
明确地被提及为预期的添加内容。它们被列为header list,作者无法控制它。
但是,author request headers部分中的以下文字在注释中提到了它们:
- 醇>
按HTTP修改 httpRequest 的unsafe-request flag。
此时不得包含注意:如果我们能够以某种方式使其更具规范性,那将会很棒。此时forbidden headers,例如
Accept-Encoding
,Connection
,DNT
和Host
,必要时为HTTP-network-or-cache fetch 。
Accept
,Accept-Charset
和Accept-Language
。注意:
Accept
和Accept-Language
已经包含在内(除非使用fetch()
,默认情况下不包括后者),Accept-Charset
是浪费字节。有关详细信息,请参阅header list。
我发现很难判断这种添加的范围。除了auther指定的那些之外,这是“为每个HTTP添加标头”是为CORS考虑额外标头的原因吗?但为什么只有重定向? headers部分未提及在请求标头列表中添加任何其他标头。
如果我观察到的行为符合规范,那么我主要担心的是它本质上会阻止添加新的有用的HTTP头。您永远不会知道哪些网站可能会突然被破坏,因为浏览器不仅会添加它们,还会将它们包含在CORS检查中。另一方面,只考虑作者创建的脚本,将请求创建库与服务器实现相匹配就足够了,不用担心浏览器会做什么。对我来说听起来更安全。
所以我重复我的主要问题:
对于一台服务器,我刚刚通过appended向HTTP header layer division解决了这个问题,但这更像是一种解决方法。我想真正理解Safari在这里做什么,以及为什么。
有几个关于SO的问题表明Safari在CORS和重定向的组合方面存在问题:
HTTP-redirect fetch(2013)
接受的答案指出“Apple声称这是HTML规范的编写方式”而没有引用来源。听起来像configuring my Apache,除了答案早于评论。
return all headers(2014)
接受的自我回答建议服务器辅助的解决方法。
Safari Ajax cors request not following redirect(2015)
未接受的回答提到了webkit Webkit bug 112471 comment 2(未经证实),后者反过来建议HTML5 CORS request fails in safari after redirect(最近修复)。那个人在某些时候也提到Safari fails CORS request after 302 redirect标题为“CORS应该只处理脚本作者设置的请求标题”,但似乎没有就此达成明确的共识。接近结束时,DNT
标志明确命名。
bug 98838(2015)
未回答的。
右侧的类似问题列表可能会提供更多信息。
答案 0 :(得分:2)
如果您下次分开问题,可能会有所帮助。
Accept
,但我想不出会影响CORS的那个。所以,是的,我认为Safari有一个bug,但是他们最近在这个领域进行了更改,因此WebKit的夜莺或Safari技术预览可能会做得更好。