Web 开发中的 Origin 和 Site
Cross-Origin
、Cross-Site
、Same-Origin
和 Same-Site
是 Web 开发中常见的几个词,要是概念不清的话,很容易弄混。本文是对 Origin
和 Site
这两个概念的简单总结。
URL
一个 URL 可包含 scheme
、uername
、password
、host
、port
、path
、query
和 fragment
等信息。
以 https://tom:123456@example.com:8000/search?q=text#hello
为例,URL 包含的各项信息如下:
Scheme | Username | Password | Host | Port | Path | Query | Fragment |
---|---|---|---|---|---|---|---|
"https" |
"tom" |
"123456" |
"example.com" |
8000 |
"search" |
"q=text" |
"hello" |
Origin
一个 Origin
可看成是一个 Tuple:(scheme, host, port)
。如果两个 Origin
的 scheme
、host
和 port
都相同,则两个 Origin
被视为 Same-Origin
,否则被视为 Cross-Origin
(CORS 就是 Cross-Origin Resource Sharing
)。
Tuple 的性质:
\((a_1, a_2, \ldots, a_n) = (b_1, b_2, \ldots, b_n)\) 当且仅当 \(a_1 = b_1, a_2 = b_2, \ldots, a_n = b_n\)
URL A | URL B | Same-Origin / Cross-Origin |
---|---|---|
https://abc.com:443 | http://abc.com:443 | Cross-Origin(scheme 不同) |
https://abc.com:443 | https://www.abc.com:443 | Cross-Origin(host 不同) |
https://abc.com:443 | https://abc.com:500 | Cross-Origin(port 不同) |
https://abc.com:443 | https://abc.com:443 | Same-Origin(三个元素都匹配) |
https://abc.com:443 | https://abc.com | Same-Origin(scheme 为 https 时,port 默认为 443 ) |
https://abc.com/foo:443 | https://abc.com/bar:443 | Same-Origin(三个元素都匹配) |
Site
一个 Site
也可以看成是一个 Tuple:(scheme, registrable-domain-or-host)
。Same-Site
和 Cross-Site
的判断方法也类似。
其中,registrable-domain-or-host
的定义如下:
-
如果
host
的registrable domain
不为null
,则registrable-domain-or-host
等于registrable domain
的值。 -
如果
host
的registrable domain
为null
,则registrable-domain-or-host
等于host
的值。
与 registrable domain
相关的一个概念是 public suffix
(别名:effective top-level domain
/ eTLD
),两者的算法可见 Public Suffix List。
如果一个 host
的 public suffix
为 null
或者等于 host
,其 registrable domain
的值为 null
;否则,其 registrable domain
的值为 public suffix
加上前一个 label
(也被称作 eTLD + 1
)。
Host | Public Suffix | Registrable Domain | Registrable Domain or Host |
---|---|---|---|
com | com | <null> | com |
example.com | com | example.com | example.com |
www.example.com | com | example.com | example.com |
sub.www.example.com | com | example.com | example.com |
EXAMPLE.COM | com | example.com | example.com |
github.io | github.io | <null> | github.io |
abc.github.io | github.io | github.io | abc.github.io |
URL | Site |
---|---|
https://abc.com:443 | ("https", "abc.com") |
https://abc.com/foo:443 | ("https", "abc.com") |
https://whichxjy.github.io | ("https", "whichxjy.github.io") |
在 WHATWG 文档的定义中,Same-Site
的判断包括 scheme
的相等,这在某些文档中是不必要的。这种包括 scheme
判断的 Same-Site
也被称为 Schemeful Same-Site
。
URL A | URL B | Same-Site / Cross-Site |
---|---|---|
https://abc.com:443 | http://abc.com:443 | Cross-Site(scheme 不同) |
https://abc.com:443 | http://def.com:443 | Cross-Site(registrable domain 不同) |
https://abc.com:443 | https://www.abc.com:443 | Same-Site |
https://abc.com:443 | https://abc.com:500 | Same-Site |
https://abc.com:443 | https://abc.com:443 | Same-Site |
https://abc.com:443 | https://abc.com | Same-Site |
https://abc.com/foo:443 | https://abc.com/bar:443 | Same-Site |