由于浏览器设置的标头

时间:2016-09-06 17:08:09

标签: http redirect safari xmlhttprequest cors

摘要

Safari拒绝一些涉及重定向的CORS请求,声称不允许使用某些标头。但是这个标题从未被脚本请求,但是由浏览器添加,所以我认为它应该没关系。

  • Safari的行为是个错误,
  • 规格有问题,或
  • 是否有理由让事情像这样?

错误表示CORS

中不允许使用某个标头

我观察到Safari似乎比其他浏览器更严格地解释CORS协议的情况。它使用错误消息拒绝某些请求

  

[错误] 无法加载资源:Access-Control-Allow-Headers不允许使用请求标题字段....

我已经在标题字段Accept-Encoding中看到了这一点,在将该字段添加到Access-Control-Allow-Headers后,DNT重复了同样的错误。预检请求的Access-Control-Request-Headers列表中包含的其他字段为Cache-ControlOriginAccept-Language

据我所知,这只会影响重定向的请求。如果我设法立即命名最终位置,请求成功。

WHATWG XHR:请求应该没有作者设置标题

我在自己的代码中创建了XMLHttpRequest,没有任何库或框架干扰它。我绝对肯定我从未调用setRequestHeader()方法。

WHATWG XHR spec之后我会假设我的author request headers列表应为空。 Request部分声明:

  

author request headers最初为空header list

我可以在文档中看到send()的非空参数可能会触发Content-Type作为作者请求标题,但即使有这样的无参数调用,我也遇到了问题

W3C CORS:只有作者集标题才重要

W3C CORS recommendationthe 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

WHATWG Fetch从XHR

获取列表

或许W3C CORS建议是错误的地方。也许它已被simple header取代了?这写在关于cache and network error steps

的部分
  
      
  1. 标题成为请求的WHATWG Fetch living standard CORS-preflight fetch' s {{3} },不包括names和重复项,按字典顺序排序,以及header list

  2.   
  3. value 成为标题中的项目,彼此相隔0x2C。

  4.   
  5. headers CORS-safelisted request-headers预检中的 ' byte-lowercased

    < / LI>   

那么这里的标题列表是什么? SetAccess-Control-Request-Headers的生活标准之间的联系似乎是header list

  
      
  1. req 成为新的XHR,初始化如下:

         
  2.   

因此它将作者请求标题(根据我上面的考虑因素应该为空)绑定到标题列表,该标题列表用于构建所请求标题的列表。至少最初。

标题可能会被添加

当然,Fetch规范很长,并在许多位置提到术语“标题列表”。很可能在那里某处有一些条款要求添加某些标题字段。但是,我发现Accept-EncodingDNT明确地被提及为预期的添加内容。它们被列为header list,作者无法控制它。

但是,author request headers部分中的以下文字在注释中提到了它们:

  
      
  1. 按HTTP修改 httpRequest unsafe-request flag

         
        

    注意:如果我们能够以某种方式使其更具规范性,那将会很棒。此时forbidden headers,例如Accept-EncodingConnectionDNTHost,必要时为HTTP-network-or-cache fetch

      
         此时不得包含

    AcceptAccept-CharsetAccept-Language

         
        

    注意:AcceptAccept-Language已经包含在内(除非使用fetch(),默认情况下不包括后者),Accept-Charset是浪费字节。有关详细信息,请参阅header list

      
  2.   

我发现很难判断这种添加的范围。除了auther指定的那些之外,这是“为每个HTTP添加标头”是为CORS考虑额外标头的原因吗?但为什么只有重定向? headers部分未提及在请求标头列表中添加任何其他标头。

观察到的行为会很糟糕

如果我观察到的行为符合规范,那么我主要担心的是它本质上会阻止添加新的有用的HTTP头。您永远不会知道哪些网站可能会突然被破坏,因为浏览器不仅会添加它们,还会将它们包含在CORS检查中。另一方面,只考虑作者创建的脚本,将请求创建库与服务器实现相匹配就足够了,不用担心浏览器会做什么。对我来说听起来更安全。

问题

所以我重复我的主要问题:

  • Safari的行为是个错误,
  • 规格有问题,或
  • 是否有理由让事情像这样?

解决方法

对于一台服务器,我刚刚通过appendedHTTP header layer division解决了这个问题,但这更像是一种解决方法。我想真正理解Safari在这里做什么,以及为什么。

交叉链接

有几个关于SO的问题表明Safari在CORS和重定向的组合方面存在问题:

右侧的类似问题列表可能会提供更多信息。

1 个答案:

答案 0 :(得分:2)

如果您下次分开问题,可能会有所帮助。

  • WHATWG Fetch确实废弃了CORS(它定义了CORS内联)。
  • CORS仅关注在网络级别之前设置的标头(基本上只关注在API级别设置的标头)。其中一些可以由浏览器设置,例如Accept,但我想不出会影响CORS的那个。

所以,是的,我认为Safari有一个bug,但是他们最近在这个领域进行了更改,因此WebKit的夜莺或Safari技术预览可能会做得更好。