【问题标题】:When do browsers send the Origin header? When do browsers set the origin to null?浏览器何时发送 Origin 标头?浏览器何时将原点设置为空?
【发布时间】:2021-07-16 16:58:42
【问题描述】:

this Bugzilla thread(和also)可以看出,Firefox 并不总是在 POST 请求中发送 Origin 标头。 The RFC 表示不应在某些未定义的“隐私敏感”上下文中发送它。 Mozilla 定义了这些上下文 here

我想知道这些是否是 Firefox 不会发送 Origin 标头的唯一情况。据我所知,它也不会在跨域 POST 请求中发送它(尽管 Chrome 和 Internet Explorer 会),但我无法在文档中确认这一点。它是否在我遗漏的地方枚举?

【问题讨论】:

    标签: http firefox cors cross-domain fetch-api


    【解决方案1】:

    对我来说,这是在超标准表单 POST 到 localhost 上的相对 URL 上发生的,并且似乎是由具有触发的

    <meta name="referrer" content="no-referrer">
    

    &lt;head&gt;.

    改成

    <meta name="referrer" content="same-origin">
    

    似乎让 Firefox 更快乐。

    【讨论】:

    • 简单快捷,谢谢
    【解决方案2】:

    就相关规范的实际要求而言,答案分为几个部分:

    • 当浏览器必须在内部将源设置为将被序列化为null的值时
    • 当浏览器必须发送 Origin 标头时

    以下是详细信息:

    当浏览器必须将 origin 设置为将被序列化为 null 的值时

    HTML 规范使用术语opaque origin 并将其定义为“内部值”:

    没有序列化,它可以从(它被序列化为“null”每个源的 ASCII 序列化)重新创建,唯一有意义的操作是测试相等性

    换句话说,HTML 规范在任何地方都说不透明的来源,您可以将其翻译为null

    HTML 规范要求浏览器在这些情况下设置一个不透明的来源或唯一的来源:

    1. Cross-origin images (including cross-origin img elements)
    2. Cross-origin media data (including cross-origin video and audio elements)
    3. Any document generated from a data: URL
    4. Any iframe with a sandbox attribute that doesn’t contain the value allow-same-origin
    5. Any document programmatically created using createDocument(), etc.
    6. Any document that does not have a creator browsing context
    7. Responses that are network errors
    8. The Should navigation response to navigation request of type from source in target be blocked by Content Security Policy? algorithm returns Blocked when executed on a navigate response

    在一种情况下,Fetch 规范要求浏览器将原点设置为“全局唯一标识符”(这基本上与“不透明原点”的含义相同,基本上表示 null...):

    1. Redirects across origins

    URL 规范要求浏览器在以下情况下设置不透明来源:

    1. For blob: URLs
    2. For file: URLs
    3. For any other URLs whose scheme is not one of http, https, ftp, ws, wss, or gopher

    但是请注意,仅仅因为浏览器在内部设置了一个不透明的来源——本质上是null——并不一定意味着浏览器会发送一个Origin 标头。因此,有关浏览器何时必须发送 Origin 标头的详细信息,请参阅此答案的下一部分。


    当浏览器必须发送 Origin 标头时

    浏览器发送 Origin 标头用于由 fetch() 或 XHR 调用或 JavaScript 库(axios、jQuery 等)中的 ajax 方法发起的跨域请求 - 但不适用于普通页面导航(也就是说,当您直接在浏览器中打开网页时),而不是(通常)嵌入网页中的资源(例如,不适用于 CSS 样式表、脚本或图像)。

    但这种描述是一种简化。当浏览器发送Origin 标头时,除了跨域XHR/fetch/ajax 调用之外,还有一些情况是浏览器发送Origin 标头以获取嵌入式资源。所以下面是更长的答案。


    就规范要求而言:规范要求仅针对 Fetch 规范定义为 CORS request 的任何请求发送 Origin 标头:

    CORS 请求 是包含 Origin 标头的 HTTP 请求。它不能被可靠地识别为参与 CORS 协议,因为 Origin 标头也包含在方法既不是 GET 也不是 HEAD 的所有请求中

    所以,规范的含义是:Origin 标头在所有跨域请求中发送,它也始终为所有 POSTPUT、@987654374 发送@ 和 DELETE 请求——即使对于 same-origin POSTPUTPATCHDELETE 请求(根据 Fetch 中的定义实际上是“CORS 请求”——即使它们是同源的)。*


    浏览器必须发送 Origin 标头的其他情况是使用设置了“CORS 标志”的请求的任何情况 — 就 HTTP(S) 请求而言,该标志是 except when the request mode is navigate, websocket, same-origin, or no-cors

    XHR 总是 将模式设置为cors。但是使用 Fetch API,这些请求模式是您可以使用 fetch(…) 方法的 init-object 参数的 mode 字段设置的模式:

    fetch("http://example.com", { mode: 'no-cors' }) // no Origin will be sent
    

    字体请求始终将模式设置为 cors,因此始终具有 Origin 标头。

    对于任何带有a crossorigin attributeaka“CORS 设置属性”)的元素,HTML 规范要求浏览器将请求模式设置为cors(并发送Origin 标头)。

    否则,对于嵌入式资源——任何具有发起请求的 URL 属性的元素(&lt;script src&gt;、样式表、图像、媒体元素)——请求的模式默认为 no-cors;并且由于这些请求是 GET 请求,这意味着,根据规范,浏览器不会为它们发送 Origin 标头。

    当 HTML 表单元素发起 POST 请求时,那些 POSTs 的模式也默认为 no-cors — 就像嵌入式资源的模式默认为 no-cors 一样。但是,与 no-cors 模式 GET 对嵌入式资源的请求不同,浏览器确实会为那些从 HTML 表单元素发起的 no-cors 模式 POSTs 发送 Origin 标头。

    原因是,如本答案前面所述,浏览器总是在所有 POSTPUTPATCHDELETE 请求中发送 Origin 标头。

    此外,为了完整起见,为了清楚起见:对于导航,浏览器不发送 Origin 标头。也就是说,如果用户直接导航到某个资源——通过将 URL 粘贴到浏览器地址栏中,或者通过来自另一个 Web 文档的链接——那么浏览器不会发送 Origin 标头。


    要求浏览器为所有CORS请求发送Origin标头的algorithm in the Fetch spec是这样的:

    要附加一个请求 Origin 标头,给定一个请求 request,运行以下步骤:

    1。让 serializedOrigin 成为使用 request 对请求源进行字节序列化的结果。
    2。如果request的response tainting是“cors”或者request的mode是“websocket”,那么
        将Origin/serializedOrigin 附加到request 的标头列表中。
    3.否则,如果request的方法既不是GET也不是HEAD
        然后:[在这种情况下也发送 Origin 标头]

    第 2 步要求在所有跨域请求中发送 Origin 标头——因为所有跨域请求都将其响应污染设置为“cors”。

    但是第 3 步还需要为 same-origin POSTPUTPATCHDELETE 请求发送 Origin 标头(其中根据 Fetch 中的定义,实际上是“CORS 请求”——即使它们是同源的)。

    由于change that was made to the spec on 2016-12-09,上面描述了 Fetch 规范当前如何定义要求。在那之前,要求是不同的:

      •  以前没有为同源 POST 发送 Origin
    •  以前没有从 &lt;form&gt; 发送跨域 POST 的 Origin(没有 CORS)

    所以问题描述的 Firefox 行为是规范以前要求的,而不是当前要求的。

    【讨论】:

    • 你能概括一下吗:总是包含标头,除非它不是 Get/Head 请求 think [Post],如果它是由 JS XHR 制作的,那么模式是 CORS,然后标头也包括在内,但是,使用 fetch 您可以更改模式并且不会包含标题。这是否意味着在不使用 JS (fetch/xhr) 的情况下发出 get 请求的 img 标签不会发送标头来源和引用来源
    • 你知道是否有任何方法可以在 ajax CORS 请求中将原始标头设置为 null,而无需创建沙盒 iframe 并使用 postMessages 与其通信 - 希望进行匿名请求
    猜你喜欢
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    相关资源
    最近更新 更多