什么是window.origin
?它似乎没有在通常的地方记录下来。
看起来它可能与window.location.origin
非常相似 - 例如,在堆栈溢出上,两者都返回
https://stackoverflow.com
但是在iframe
内部,它们是不同的:
console.log(window.location.origin);
console.log(window.origin);
https://stacksnippets.net null
嵌入的代码段位于没有allow-same-origin
的iframe
内。如果您更改 iframe,例如,如果您编辑 Stack Overflow 的 HTML 并手动添加属性:
<iframe name="313b857b-943a-7ffd-4663-3d9060cf4cb6" sandbox="allow-same-origin allow-forms allow-modals allow-scripts" class="snippet-box-edit" frameborder="0" style="">
^^^^^^^^^^^^^^^^^^
然后运行代码段,你会得到:
https://stacksnippets.net https://stacksnippets.net
在其他具有<iframe>
的网站上也表现出相同的行为。
谷歌似乎没有任何关于该主题的权威链接。搜索确切的短语 + Javascript 会得到许多与iframe
和postMessage
相关的结果,但没有精确描述window.origin
实际上是什么。
从子iframe
调用postMessage
似乎会导致父窗口收到一条消息,其中origin
属性与子帧的window.origin
匹配 - 如果没有allow-same-origin
,它是null
,否则它看起来与子帧的window.location.origin
相同。
以上是我认为我从猜测和检查中得出的,但我远未确定。我希望得到确认/解释,最好是指向权威来源的链接。
WindowOrWorkerGlobal.origin 返回环境的原点,Location.origin 返回环境的 URL 原点。
不幸的是,堆栈片段零来源的帧将成为一个令人困惑的例子......
冒着解释规范本身的风险,假设我们在https://example.com
,然后从那里创建一个没有src
属性的新
var frame = document.createElement("iframe")
frame.onload = function() {
var frameWin = frame.contentWindow;
console.log(frameWin.location.href); // "about:blank"
console.log(frameWin.location.origin) // "null"
console.log(frameWin.origin) // "https://example.com"
}
document.body.appendChild(frame);
现场示例
我们frameWin
的location
是"about:blank"
的,它的location.origin
是"null"
的,"about:blank"
因为它是一个不透明的起源。
然而,框架的窗口frameWin
将自己的origin
设置为父窗口("https://example.com"
)之一,这是在frameWin
的浏览上下文初始化时设置的。
如果您希望稍微深入了解规格,以下是上一个示例的相关步骤:
- 在创建
frame
: https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element:about:blank
如果元素没有指定
src
属性,或者其值为空字符串,则url
URL "about:blank"。
- 为
frame
创建新的浏览上下文时 https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts:about:blank
如果 invocationOrigin 不为 null,并且 url 为 about:blank,则返回 invocationOrigin。
所以这里已经确定新的浏览上下文的origin
是invocationOrigin
的,即确实创建了frame
的浏览上下文的origin
,而location
使用的url
是"about:blank"
。
现在,StackSnippets 沙盒帧的情况有点特别,因为它们确实有一个src
,因此有一个元组源 URL,但由于它们的sandbox
属性使其源不透明,它们的行为将与上一个示例中公开的内容相反,使self.origin
返回"null"
并location
返回 iframe 的src
的URL。
一个非常有趣的问题! 😊
我们可以从一些调查开始 - 让我们看看window
的输出
console.log(window)
那个文件很大...窗口接口表示包含 DOM 文档的窗口;文档属性指向该窗口中加载的 DOM 文档,并描述窗口和 WorkerGlobalScope 共有的几个功能。
更多细节在这里
但是,您希望看到一个非常特殊的属性window.origin
。
window.origin正如你所看到的,对于堆栈溢出(代码片段)来说,这个非常无聊,json obj 返回的窗口带来:
"origin": "null"
此响应是窗口告诉我们原点不相同并且不允许该窗口具有相同原点的方式。当你扣除自己时,对iframe
来说很常见!
你也看到window.location
不那么无聊了......因为它包含更多数据,因为位置接口表示它链接到的对象的位置 (URL),很酷的是,对其所做的任何更改都会反映在它相关的对象上。所以这就是为什么我们在这里没有得到一个空
。窗口.位置...
"location": {
"ancestorOrigins": {
"0": "https://stackoverflow.com",
"length": 1,
"item": function item() {
[native code
]
},
"contains": function contains() {
[native code
]
}
},
"origin": "https://stacksnippets.net",
...
}
我认为它没有记录在案,因为两者都相同,几乎没有区别, 在大多数情况下,选择使用哪个选项并不重要。但是,在某些情况下,其中一个优于另一个,例如:
- 如果在 iframe 或另一个与当前窗口已经具有不同来源的窗口中设置新 URL(例如,iframe 的域与加载它的文档不同,并且您想要更改 iframe 的 URL),则同源策略冲突将使用窗口。 位置来设置新 URL。这是因为 location.href 在从不同的源(域)调用时是只读的。
- 如果在 JavaScript 中使用严格使用可能会导致异常,如果使用 window. 位置,因为您本质上是为对象分配一个字符串,所以这里最好使用 full window.location.href。
请参阅此问题以供参考。
位置描述当前页面的 URL。它可以通过窗口获得。位置属性。
<a id='foo' href='#bar'>Go to #bar</a>
<div style='height: 1000px'></div>
<a id='bar' href='#foo'>Go to #foo</a>
<script>
var printHash = function() {
console.log("'" + window.location.hash + "'");
};
// Print initial hash
printHash();
window.onhashchange = printHash;
</script>`enter code here`
更多信息: Internet Explorer 无法访问 window.location.origin,这很糟糕,因为它是一个非常方便的变量,但我们可以通过相当直接的检查来使其工作,因为我们访问 .origin;
if (!window.location.origin) {
window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
}