When do browsers send the Origin header? When do b

2020-01-28 04:39发布

As you can see from this Bugzilla thread (and also), Firefox does not always send an Origin header in POST requests. The RFC states that it should not be sent in certain undefined "privacy-sensitive" contexts. Mozilla defines those contexts here.

I'd like to know whether these are the only situations in which Firefox will not send the Origin header. As far as I can tell, it also will not send it in cross-origin POST requests (though Chrome and Internet Explorer will), but I can't confirm that in the documentation. Is it enumerated somewhere that I'm missing?

1条回答
Viruses.
2楼-- · 2020-01-28 05:01

As far as what the specs require, the question above needs to be divided into a couple of answers:

  • When browsers must send the Origin header
  • When browsers must internally set origin to a value that’ll get serialized as null

I doubt that what Firefox requires around this (where it’s different from the spec) is enumerated. But as far as enumerating the spec requirements, here they are, in exhaustive detail, in two parts:

When browsers must send the Origin header

The answer to the question When must browsers must send the Origin header? is: The Origin header is sent only for any request which the Fetch spec defines as a CORS request:

A CORS request is an HTTP request that includes an Origin header. It cannot be reliably identified as participating in the CORS protocol as the Origin header is also included for all requests whose method is neither GET nor HEAD.

The actual statement in the Fetch spec that requires browsers to send the Origin header for all requests whose method is neither GET nor HEAD is this:

If the CORS flag is set or httpRequest’s method is neither GET nor HEAD, then append Origin/httpRequest’s origin, serialized and UTF-8 encoded, to httpRequest’s header list.

So that requires browsers to send Origin for all POST requests, including same-origin POSTs (which by definition in Fetch are actually “CORS requests”—even though they’re same-origin).


Note: The above describes how the Fetch spec currently defines the requirements, due to a change that was made to the spec on 2016-12-09. Up until then the requirements were different:

  • previously no Origin was sent for a same-origin POST
  • previously no Origin was sent for cross-origin POST from a <form> (without CORS)

So I think the Firefox behavior described in the question conforms to what the spec previously required, but not what the spec currently requires.


The other cases when browsers must send the Origin header are any cases where a request is made with the “CORS flag” set—which, as far as HTTP(S) requests is except when the request mode is navigate, websocket, same-origin, or no-cors.

XHR always sets the mode to cors. But with the Fetch API, those request modes are the ones you can set with the mode field of the init-object argument to the fetch(…) method:

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

Along with that, for any element with a crossorigin attribute (aka “CORS setting attribute), the HTML spec requires browsers to set the request mode to cors (and to send the Origin header).

Otherwise, for any elements that initiate requests (scripts, stylesheets, images, media elements), the mode for the requests defaults to no-cors, which means no Origin header is sent for them.

So that above are the details about the conditions under which browsers send the Origin header.

The next part of the answer is about when the origin value will be set to null.

When browsers must set origin to a value that’ll get serialized as null

Separate from requirements for when browsers must send the Origin header are requirements for when browsers must set an origin to null, which are defined in the following specs:

The HTML spec uses the term opaque origin and says this:

An internal value, with no serialization it can be recreated from (it is serialized as "null" per ASCII serialization of an origin), for which the only meaningful operation is testing for equality.

In other words everywhere the HTML spec says opaque origin, you can translate that to null.

The HTML spec requires browsers to set an opaque origin or unique origin in the following cases:

  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

The Fetch spec requires browsers to set the origin to a “globally unique identifier” (which basically means the same thing as “opaque origin” which basically means null…) in one case:

  1. Redirects across origins

The URL spec requires browsers to set an opaque origin in the following cases:

  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.

But it’s important to understand that just because the browser has internally set an opaque origin—essentially null—that doesn’t necessarily mean the browser will send an Origin header. So see the first part of this answer for details about when browsers must send the Origin header.

查看更多
登录 后发表回答