http - 由于浏览器设置的 header ,Safari 拒绝重定向的 CORS 请求

标签 http redirect safari xmlhttprequest cors

概括

Safari 拒绝了一些涉及重定向的 CORS 请求,声称某些 header 是不允许的。但是该 header 从未被脚本请求过,而是由浏览器添加的,所以我认为这无关紧要。

  • Safari 的行为是否是一个错误,
  • 规范有问题吗,或者
  • 有没有理由让事情变成这样?

  • 错误表明 CORS 中不允许某些 header

    我正在观察 Safari 似乎比其他浏览器更严格地解释 CORS 协议(protocol)的情况。它拒绝某些带有错误消息的请求

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



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

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

    WHATWG XHR:请求应该没有作者设置的 header

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

    关注 WHATWG XHR spec因此,我假设我的 author request headers列表应该是空的。 Request部分指出:

    The author request headers is an initially empty header list.



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

    W3C CORS:只有作者设置的标题才重要

    W3C CORS recommendation描述 the Access-Control-Request-Headers field由作者请求 header 组成:

    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).



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

    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 从 XHR 获取列表

    也许 W3C CORS 推荐是错误的地方。也许它已被 WHATWG Fetch living standard 取代?在其关于 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.



    那么这里的标题列表是什么?生活水平之间的联系XHRFetch似乎是 the send() method specification .

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



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

    标题可能会被添加

    当然,Fetch 规范很长,很多地方都提到了“header list”这个词。很可能在某处有一些条款要求添加某些标题字段。但我看不到 Accept-Encoding 的部分或 DNT明确提到作为预期的补充。它们被列为 forbidden headers作者不应该控制的。

    但是,以下来自 HTTP-network-or-cache fetch 的文本部分在注释中提到了它们:

    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 , 和 Accept-Language此时不应包括在内。

      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.



    2. 我发现很难判断这个添加的范围。除了作者指定的那些之外,“为每个 HTTP 添加 header ”是否是 CORS 考虑额外 header 的原因?但为什么只在重定向的情况下? HTTP-redirect fetch部分没有提到向请求 header 列表添加更多 header 。

      观察到的行为会很糟糕

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



      所以我重复我的主要问题:
    3. Safari 的行为是否是一个错误,
    4. 规范有问题吗,或者
    5. 有没有理由让事情变成这样?

    6. 解决方法

      对于一台服务器,我刚刚通过 configuring my Apache 解决了这个问题至 return all headers ,但这更像是一种解决方法。我想真正了解 Safari 在这里做什么,以及为什么。

      交叉链接

      SO上有几个问题表明Safari在CORS和重定向的组合方面存在问题:
    7. Safari Ajax cors request not following redirect (2013)
      接受的答案指出“Apple 声称这是编写 HTML 规范的方式”,但没有引用来源。听起来像 Webkit bug 112471 comment 2除了那个答案早于评论。
    8. HTML5 CORS request fails in safari after redirect (2014)
      接受的自我回答提出了服务器辅助的解决方法。
    9. Safari fails CORS request after 302 redirect (2015)
      未接受的答案提到了 webkit bug 98838 (未经证实)这反过来又暗示 bug 112471 (最近修复)。那个人在某些时候还提到了 bug 63460标题为“CORS 应该只处理由脚本作者设置的请求 header ”,但似乎没有就此达成明确的共识。接近尾声DNT标志是明确命名的。
    10. Safari turns Simple Cors Request into Preflight after 302 redirect (2015)
      未答复。

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

    最佳答案

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

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

  • 所以是的,我认为 Safari 有一个错误,但他们最近一直在这方面做出改变,所以 WebKit nightlies 或 Safari Technology Preview 可能会做得更好。

    关于http - 由于浏览器设置的 header ,Safari 拒绝重定向的 CORS 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39354408/

    相关文章:

    animation - Safari 11 中的 SVG 动画错误

    CSS 关键帧动画 safari

    http - Aurelia 授权响应

    javascript - "XMLHttpRequest cannot load"错误?

    javascript - 带有字符 ":"的url是什么意思

    redirect - 如何使用参数对单个 URL 进行 301 永久重定向

    javascript - 如何设置CSS规则只适用于iPhone浏览器而不使用JS?

    svn - CruiseControl.NET 是否支持通过 http 协议(protocol)访问存储库?

    javascript - 禁用缓存后,Chrome CORS 请求会更快吗?

    javascript - window.location.href 错误的脚本