浏览器何时发送Origin标头?浏览器何时将原点设置为null? [英] When do browsers send the Origin header? When do browsers set the origin to null?
问题描述
您可以从此Bugzilla线程(和也),Firefox不会总是在POST请求中发送Origin头。 RFC 声明不应以某些未定义的对隐私敏感的形式发送上下文。 Mozilla在此处定义了这些上下文。
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.
我想知道这些是否是Firefox不发送Origin标头的唯一情况。据我所知,它也不会在跨域POST请求中发送(尽管Chrome和Internet Explorer会发送),但是我无法在文档中确认。
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?
推荐答案
根据相关规范的实际要求,答案可以划分为分为两部分:
As far as what the relevant specs actually require, the answer can be divided into a couple parts:
- 当浏览器必须在内部将原点设置为将被序列化为
null
- 何时浏览器必须发送Origin标头
- When browsers must internally set an origin to a value that’ll get serialized as
null
- When browsers must send the Origin header
以下是详细信息:
当浏览器必须将origin设置为将被序列化为 null
When browsers must set origin to a value that’ll get serialized as null
HTML规范使用术语不透明的来源,并这样说:
The HTML spec uses the term opaque origin and says this:
内部值,无需序列化即可重新创建(序列化为 null(按原点的ASCII序列化),唯一有意义的操作就是测试是否相等。
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.
在所有HTML规范说 opaque origin 的命令中,您都可以将其翻译为 null
。
In other words everywhere the HTML spec says opaque origin, you can translate that to null
.
HTML规范在以下情况下需要浏览器设置不透明的原点或唯一的原点:
The HTML spec requires browsers to set an opaque origin or unique origin in the following cases:
- 跨源图片(包括跨源
img
元素) - 跨源媒体数据(包括跨域
视频
和音频
元素) - 从
数据生成的任何文档:
URL - 任何
iframe
,其中的沙盒
属性不包含值allow-same-origin a>
-
使用 createDocument()
以编程方式创建的任何文档,等等。 - 任何没有创建者浏览上下文的文档
- 属于网络错误的响应
- 是否应通过内容安全策略阻止对来自目标源的类型的导航请求的导航响应?算法在对导航响应执行时返回已阻止 a>
- Cross-origin images (including cross-origin
img
elements) - Cross-origin media data (including cross-origin
video
andaudio
elements) - Any document generated from a
data:
URL - Any
iframe
with asandbox
attribute that doesn’t contain the valueallow-same-origin
- Any document programmatically created using
createDocument()
, etc. - Any document that does not have a creator browsing context
- Responses that are network errors
- 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
...)情况:
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:
- Redirects across origins
URL规范要求浏览器在以下情况下设置不透明的原点:
The URL spec requires browsers to set an opaque origin in the following cases:
- For
blob:
URLs - For
file:
URLs - For any other URLs whose scheme is not one of
http
,https
,ftp
,ws
,wss
, orgopher
.
但是了解这一点很重要,因为浏览器内部设置了一个不透明的原点(本质上是 null
),但这并不是必要从根本上讲,浏览器将发送 Origin
标头。因此,有关何时浏览器必须发送 Origin
标头的详细信息,请参见此答案的下一部分。
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 next part of this answer for details about when browsers must send the Origin
header.
何时浏览器必须发送来源标头
问题浏览器何时必须发送起源标头?的答案是: Origin
标头仅针对Fetch规范定义为 CORS请求 :
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:
一个 CORS请求是一个包含
Origin
标头。无法可靠地将其标识为参与CORS协议,因为对于方法都不是GET $ c $的所有请求,还包含
Origin
标头c>或HEAD
。
A CORS request is an HTTP request that includes an
Origin
header. It cannot be reliably identified as participating in the CORS protocol as theOrigin
header is also included for all requests whose method is neitherGET
norHEAD
.
Fetch规范中的实际声明,该声明要求浏览器为所有请求发送 Origin
标头方法既不是 GET
也不是 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:
如果设置了 CORS标志或 httpRequest的方法既不是
GET
也不是HEAD
,然后将Origin
/ httpRequest 的来源(经过序列化和UTF-8编码)附加到httpRequest的标题列表中。
If the CORS flag is set or httpRequest’s method is neither
GET
norHEAD
, then appendOrigin
/httpRequest’s origin, serialized and UTF-8 encoded, to httpRequest’s header list.
因此,这要求浏览器发送 all << c $ c> Origin POST
请求,包括同源的 POST
s(根据Fetch的定义,实际上是 COR S请求(即使它们是相同来源的。)。
So that requires browsers to send Origin
for all POST
requests, including same-origin POST
s (which by definition in Fetch are actually "CORS requests"—even though they’re same-origin).
注意:上面介绍了当前获取规范的方式定义了要求,这是由于对2016年12月9日的规范进行了更改一个>。在此之前,要求是不同的:
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:
- 以前没有为同一来源的POST发送
来源
- 以前没有从
< form> $ c发送跨域POST的
来源
$ c>(没有CORS)
- previously no
Origin
was sent for a same-origin POST - previously no
Origin
was sent for cross-origin POST from a<form>
(without CORS)
所以我认为问题中描述的Firefox行为符合先前的要求,但不是规范当前的要求。
So I think the Firefox behavior described in the question conforms to what the spec previously required, but not what the spec currently requires.
浏览器必须发送 Origin的其他情况
标头是在设置了 CORS标志的情况下发出请求的任何情况,就HTTP(S)请求而言,该请求为 例外,当请求模式是 navigate
, websocket
,同源
或无费用
。
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 始终将模式设置为 cors
。但是,使用Fetch API,可以使用 fetch(…)的init-object参数的
方法: mode
字段设置那些请求模式。
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
此外,对于任何 a crossorigin
属性( aka CORS设置属性),HTML规范要求浏览器将请求模式设置为 cors
(并发送 Origin $ c $
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).
否则,对于任何具有带有发起请求的URL的属性的元素(< script src>
,样式表,图片,媒体元素),则请求的模式默认为 no-cors
,这意味着不发送 Origin
标头为他们。
Otherwise, for any elements having attributes with URLs that initiate requests (<script src>
, stylesheets, images, media elements), the mode for the requests defaults to no-cors
, which means no Origin
header is sent for them.
这篇关于浏览器何时发送Origin标头?浏览器何时将原点设置为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!