“同网站”和“同源”这两个词经常被提及,但常常会被误解。例如,它们用于网页转换、fetch()
请求、Cookie、打开弹出式窗口、嵌入式资源和 iframe 的上下文。本页面介绍了它们是什么以及它们之间的不同之处。
原点
![原点](https://web.developers.google.cn/static/articles/same-site-same-origin/image/origin-scheme.png?authuser=8&hl=nb)
“源”是架构(也称为协议,例如 HTTP 或 HTTPS)、主机名和端口(如果已指定)的组合。例如,如果网址为 https://www.example.com:443/foo
,则“origin”为 https://www.example.com:443
。
“Same-origin”和“cross-origin”
在 scheme、主机名和端口组合方面均相同的网站会被视为“同源”网站。所有其他属性均被视为“跨源”。
出发地 A | 源站 B | “Same-origin”还是“cross-origin”? |
---|---|---|
https://www.example.com:443 | https://www.evil.com:443 | 跨源:不同网域 |
https://example.comexample.com:443 | 跨源:不同的子网域 | |
https://login.example.com:443 | 跨源:不同的子网域 | |
http://www.example.com:443 | 跨源:不同架构 | |
https://www.example.com:80 | 跨域:不同端口 | |
https://www.example.com:443 | 同源:完全匹配 | |
https://www.example.com | 同源:隐式端口号 (443) 匹配 |
网站
![网站 (TLD+1)](https://web.developers.google.cn/static/articles/same-site-same-origin/image/site-tld1-ae5ebbc587fbe.png?authuser=8&hl=nb)
根区数据库中列出了顶级域名 (TLD),例如 .com
和 .org
。在前面的
示例中,“site”是架构、TLD 以及该域名前面一部分(我们称之为 TLD+1)的组合。例如,如果网址为 https://www.example.com:443/foo
,则“网站”为 https://example.com
。
公共后缀列表和 eTLD
对于包含 .co.jp
或 .github.io
等元素的网域,仅使用 .jp
或 .io
不足以识别“网站”。因此无法通过算法确定特定 TLD 的可注册域名级别。为此,公共后缀列表定义了一个公共后缀列表,该后缀也称为有效 TLD (eTLD)。eTLD 列表位于 publicsuffix.org/list 中。
如需标识包含 eTLD 的网域的“网站”部分,请采用与 .com
示例相同的做法。以 https://www.project.github.io:443/foo
为例,架构为 https
,eTLD 为 .github.io
,eTLD+1 为 project.github.io
,因此 https://project.github.io
被视为此网址的“网站”。
![网站 (eTLD+1)](https://web.developers.google.cn/static/articles/same-site-same-origin/image/site-etld1-2ffebe0e355bd.png?authuser=8&hl=nb)
“同网站”和“跨网站”
具有相同 scheme 和 eTLD+1 的网站会被视为“同一网站”。采用不同 scheme 或 eTLD+1 的网站属于“跨网站”网站。
出发地 A | 源站 B | “同网站”还是“跨网站”? |
---|---|---|
https://www.example.com:443 | https://www.evil.com:443 | 跨网站:不同网域 |
https://login.example.com:443 | 同网站:不同的子网域无关紧要 | |
http://www.example.com:443 | 跨网站:不同方案 | |
https://www.example.com:80 | 同网站:不同端口无关紧要 | |
https://www.example.com:443 | 同网站:完全匹配 | |
https://www.example.com | 同网站:端口无关紧要 |
“无架构同网站”
![无协议同网站](https://web.developers.google.cn/static/articles/same-site-same-origin/image/schemeless-same-site-3ba215c9666cd.png?authuser=8&hl=nb)
“同网站”的定义已更改为网站的一部分包含网址架构,以防止将 HTTP 用作安全系数低的通道。之前没有架构比较的“同网站”概念现在称为“无协议同网站”。例如,http://www.example.com
和 https://www.example.com
被视为无协议同站点但不是同站点,因为只有 eTLD+1 部分很重要,而不会被考虑架构。
出发地 A | 源站 B | “无架构同网站”还是“跨网站”? |
---|---|---|
https://www.example.com:443 | https://www.evil.com:443 | 跨网站:不同网域 |
https://login.example.com:443 | 无架构同网站:不同的子网域无关紧要 | |
http://www.example.com:443 | 无架构同网站:不同架构无关紧要 | |
https://www.example.com:80 | 无架构同网站:不同端口无关紧要 | |
https://www.example.com:443 | 无架构同网站:完全匹配 | |
https://www.example.com | 无架构同网站:端口无关紧要 |
如何检查请求是“同网站”“同源”还是“跨网站”
所有新型浏览器均使用 Sec-Fetch-Site
HTTP 标头发送请求。标头具有以下某个值:
cross-site
same-site
(指采用协议的同网站)same-origin
none
您可以检查 Sec-Fetch-Site
的值以确定请求是同网站、同源还是跨网站。
您可以合理信任 Sec-Fetch-Site
标头的值,原因如下:
- JavaScript 无法修改以
Sec-
开头的 HTTP 标头 - 浏览器始终会设置这些标题。