【问题标题】:Safari rejects redirected CORS request due to browser-set headers由于浏览器设置的标头,Safari 拒绝重定向 CORS 请求
【发布时间】:2023-03-03 17:45:02
【问题描述】:

总结

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 中按字典顺序排列的标头字段名称的逗号分隔列表,每个converted to ASCII lowercase(即使有一个或多个simple header)。

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

如果author request headers 中每个标头的字段名称不是ASCII case-insensitive 匹配headers 中的标头字段名称之一,并且标头不是simple header,则应用@ 987654337@.

WHATWG Fetch 从 XHR 获取列表

也许 W3C CORS 建议是错误的地方。也许它已被WHATWG Fetch living standard 取代?在其部分中写到CORS-preflight fetch

  1. headers 成为 requestheader listheadersnames,不包括 CORS-safelisted request-headers 和重复项,按字典顺序排序,和byte-lowercased

  2. valueheaders 中的项目,彼此之间用 0x2C 隔开。

  3. Set Access-Control-Request-Headerspreflightheader list 中的 value

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

  1. req为一个新的request,初始化如下:

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

可能会添加标题

当然,Fetch 规范很长,并且在很多处提到了“标题列表”一词。很可能那里有一些条款要求添加某些标题字段。但我看不到任何部分明确提及Accept-EncodingDNT 作为预期添加。它们被列为forbidden headers,作者不应对其进行控制。

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

  1. 根据 HTTP 修改 httpRequestheader list

    注意:如果我们能以某种方式使其更加规范,那就太好了。此时headersAccept-EncodingConnectionDNTHost,如有必要,应为appended

    此时不得包含AcceptAccept-CharsetAccept-Language

    注意:AcceptAccept-Language已经包含了(除非使用fetch(),默认不包含后者),Accept-Charset是浪费字节。有关详细信息,请参阅HTTP header layer division

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

观察到的行为会很糟糕

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

问题

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

  • Safari 的行为是否存在错误,
  • 规格是否有问题,或者
  • 有这样的原因吗?

解决方法

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

交叉链接

SO上有几个问题表明Safari在CORS和重定向的结合上存在问题:

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

【问题讨论】:

    标签: http redirect safari xmlhttprequest cors


    【解决方案1】:

    如果你下次分开提问可能会有所帮助。

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

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

    【讨论】:

      猜你喜欢
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多