Safari由于浏览器设置标头而拒绝重定向的CORS请求 [英] Safari rejects redirected CORS request due to browser-set headers

查看:3352
本文介绍了Safari由于浏览器设置标头而拒绝重定向的CORS请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘要



Safari拒绝一些涉及重定向的CORS请求,声称不允许某些标题。




  • Safari的行为是一个

  • 是否有问题,或

  • 有什么原因吗?



错误表示CORS中不允许有某个标题



我观察到Safari出现的情况比其他浏览器更严格地解释CORS协议。 [错误] 无法加载资源:请求头字段... ...不允许由访问控制允许标头


看到这个头字段 Accept-Encoding ,并将该字段添加到 Access-Control-Allow-Headers 使用 DNT 重复相同的错误。预检请求的 Access-Control-Request-Headers 列表中包含的其他字段为 Cache-Control 原始接受语言



告诉,这只影响被重定向的请求。



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



我在自己的代码中创建了 XMLHttpRequest ,没有任何库或框架干扰它。我绝对肯定我从未呼叫过



WHATWG XHR规范因此,我假设我的作者请求标头列表应为空。 请求部分说明:


作者请求标头最初为空< a href =https://fetch.spec.whatwg.org/#concept-header-list =nofollow>标头列表。


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



W3C CORS:只有作者集标题有用



W3C CORS推荐说明了 Access-Control-Request-Headers 字段由作者请求标头组成:


如果作者请求标头不为空时包含访问控制请求标头头作为标头字段值以逗号分隔的头字段名称列表作者请求标头,每个转换为ASCII小写(即使一个或多个是 simple header )。


根据该规范,我可以看到错误的原因是:


如果作者请求标头不是 ASCII不区分大小写匹配其中一个标题字段名称在 标头中,并且标题不是简单标题,应用缓存和网络错误步骤




WHATWG Fetch从XHR获取列表



也许W3C CORS的建议是错误的地方看。也许它已被 WHATWG Fetch生活标准取代?在其中有关 CORS-预检取的部分写道



  1. headers 请求标题列表 headers ,不包括 CORS安全列表请求 - 标题和重复项,按字典顺序排序,以及字节小写。 p>

  2. li>
  3. 设置 < a href =https://fetch.spec.whatwg.org/#http-access-control-request-headers =nofollow> 访问控制请求标头 -listrel =nofollow>标题列表



那么这里的标题列表是什么? XHR 抓取似乎是 send()方法规范



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




    • 方法 请求方法

    • 网址 请求网址

    • 标题列表 作者请求标题

    • unsafe-request标志设置。

    • [...]



    • 所以它绑定作者请求头(根据我上面的考虑应该是空的)到头列表,用于构建请求的头的列表。至少最初。



      标题可能会被添加



      当然,Fetch规范很长,在许多 地方中的头部列表。很可能有一些子句在某处,其中强制添加某些头字段。但我看不到 Accept-Encoding DNT 被明确地提到作为预期添加的部分。它们列为禁止标题,作者不应该对其进行控制。



      但是,下面的 HTTP-network-or-cache fetch section in a note:



      1. 修改 httpRequest


        注意:如果我们可以使用这更规范不知何故。此时标头,例如接受编码连接 DNT 主机 ,必要时附加


        接受 Accept-Charset Accept-Language


        注意:已经包含接受 Accept-Language (除非 fetch使用,默认情况下不包括后者), Accept-Charset 是浪费字节。有关详情,请参见 HTTP标头层分区



      我觉得很难判断此添加的范围。这是添加头每个HTTP的额外的头被考虑为CORS的原因,除了auther指定的?但是为什么只有在重定向的情况下? HTTP重定向抓取部分未提及向其中添加任何更多标题请求标头列表。



      观察到的行为会很糟糕



      如果我观察到的行为是根据spec,那么我的主要关注是它将基本上阻止添加新的和有用的HTTP头。你永远不会知道哪些网站可能突然崩溃,因为浏览器开始不仅添加它们,而且将它们包括在CORS检查。另一方面,只考虑作者创建的脚本,将请求创建库与服务器实现匹配就足够了,不用担心什么浏览器会做。



      问题



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




      • Safari的行为是一个错误,

      • 规格有问题,或

      • 是否有这样的原因?



      解决方法



      对于一个服务器,我只是通过配置我的Apache 来解决这个问题,以返回所有头,但这是一个解决方法。我想真正了解Safari在这里做什么,以及为什么。



      交叉链接



      SO的几个问题表明Safari在CORS和重定向的组合中存在问题:





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

      解决方案




      • WHATWG Fetch确实删除了CORS(它定义了CORS内联)。 li>
      • CORS只注意在网络级别之前设置的标头(基本上只有在API级别设置的标头)。其中一些可以由浏览器设置,例如 Accept ,但我不能想到会影响CORS的。



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


          Summary

          Safari rejects some CORS requests which involve redirects, claiming that some header is not allowed. But that header is never requested by the script, but added by the browser, so I think it should not matter.

          • Is Safari's behavior a bug,
          • is there a problem with the specs, or
          • is there a reason for things to be like this?

          Error indicates some header is not allowed in CORS

          I'm observing situations where Safari appears to interpret the CORS protocol more strictly than other browsers. It rejects certain requests with the error message

          [Error] Failed to load resource: Request header field … is not allowed by Access-Control-Allow-Headers.

          I've seen this for the header field Accept-Encoding, and after adding that field to Access-Control-Allow-Headers the same error was repeated with DNT. Other fields included in the Access-Control-Request-Headers list of the preflight request are Cache-Control, Origin and Accept-Language.

          As far as I can tell, this only affects requests which get redirected. In cases where I managed to immediately name the final location, the request succeeded.

          WHATWG XHR: Request should have no author-set headers

          I created the XMLHttpRequest in my own code, without any library or framework interfering with it. I'm absolutely certain I never called the setRequestHeader() method.

          Following the WHATWG XHR spec I would therefore assume that my author request headers list should be empty. The Request section states:

          The author request headers is an initially empty header list.

          I can read in the documentation that a non-empty argument to send() might trigger Content-Type as an author request header, but I'm experiencing problems even with such a no-argument call.

          W3C CORS: Only author-set headers should matter

          The W3C CORS recommendation describes the Access-Control-Request-Headers field as being composed of author request headers:

          If author request headers is not empty include an Access-Control-Request-Headers header with as header field value a comma-separated list of the header field names from author request headers in lexicographical order, each converted to ASCII lowercase (even when one or more are a simple header).

          And the likely reason for an error that I can see, according to that spec, would be this:

          If the field name of each header in author request headers is not an ASCII case-insensitive match for one of the header field names in headers and the header is not a simple header, apply the cache and network error steps.

          WHATWG Fetch takes the list from XHR

          Perhaps the W3C CORS recommendation is the wrong place to look. Perhaps it has been superseded by the WHATWG Fetch living standard? That writes in its section about CORS-preflight fetch

          1. Let headers be the names of request's header list's headers, excluding CORS-safelisted request-headers and duplicates, sorted lexicographically, and byte-lowercased.

          2. Let value be the items in headers separated from each other by 0x2C.

          3. Set Access-Control-Request-Headers to value in preflight's header list.

          So what is the header list here? The connection between the living standards for XHR and Fetch appears to be the send() method specification.

          1. Let req be a new request, initialized as follows:

          So it binds the author request headers (which according to my considerations above should be empty) to the header list which is used to build the list of requested headers. At least initially.

          Headers might get added

          Of course, the Fetch specification is long, and mentions the term "header list" in many places. It might well be that there is some clause somewhere in there which mandates adding certain header fields. But I see no portion where Accept-Encoding or DNT are explicitely mentioned as intended additions. They are listed as forbidden headers over which an author should have no control.

          However, the following bit of text from the HTTP-network-or-cache fetch section mentions them in a note:

          1. Modify httpRequest's header list per HTTP.

            Note: It would be great if we could make this more normative somehow. At this point headers such as Accept-Encoding, Connection, DNT, and Host, are to be appended if necessary.

            Accept, Accept-Charset, and Accept-Language must not be included at this point.

            Note: Accept and Accept-Language are already included (unless fetch() is used, which does not include the latter by default), and Accept-Charset is a waste of bytes. See HTTP header layer division for more details.

          I find it very hard to judge the scope of this addition. Is this "adding headers per HTTP" the cause for extra headers being considered for CORS, in addition to those specified by the auther? But why only in case of redirects? The HTTP-redirect fetch section does not mention adding any more headers to the list of request headers.

          Observed behavior would be bad

          If the behavior I observe were according to the spec, then my main concern would be that the it would essentially prevent the addition of new and useful HTTP headers. You'd never know which sites might suddenly get broken as browsers start to not only add them but also include them in CORS checks. On the other hand, with only author-created scripts being considered, it would be sufficient to match request creation library to server implementation, with no worries about what browsers do. Sounds like a much saner setup to me.

          Question

          So I repeat my main question:

          • Is Safari's behavior a bug,
          • is there a problem with the specs, or
          • is there a reason for things to be like this?

          Workaround

          For one server I just solved this by configuring my Apache to return all headers, but that's more of a workaround. I'd like to really understand what Safari is doing here, and why.

          Cross links

          There are several questions on SO indicating that Safari has problems with the combination of CORS and redirects:

          The list of similar questions on the right might provide further information.

          解决方案

          It might help if you split up your questions next time.

          • WHATWG Fetch indeed obsoletes CORS (it defines CORS inline).
          • CORS only pays attention to headers set before the network level (basically only those set at the API level). Some of these could be set by the browser, e.g., Accept, but I can't think of one that would affect CORS.

          So yeah, I think Safari has a bug, but they have been making changes in this area very recently, so WebKit nightlies or Safari Technology Preview might do better.

          这篇关于Safari由于浏览器设置标头而拒绝重定向的CORS请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆