javascript 检测此页面是否在跨域 iframe 内部的万无一失的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21751377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Foolproof way to detect if this page is INSIDE a cross-domain iframe
提问by user56reinstatemonica8
An answer to "Foolproof way to detect if iframe is cross domain" describes a method to test if an iframe on a page points to a same-domain or cross-domain page, working around different browsers' interpretations of the cross-domain policy and avoiding error messages that would interrupt a user or stop javascript.
“检测 iframe 是否跨域的万无一失的方法”的答案描述了一种测试页面上的 iframe 是否指向同域或跨域页面的方法,绕过不同浏览器对跨域策略的解释和避免会中断用户或停止 javascript 的错误消息。
I'm looking to do the equivalent of this but fromthe child page inside the iframe testing whether it is insidea cross-domain iframe or not.
我正在寻找与此等效的操作,但是从iframe 内的子页面测试它是否在跨域 iframe 内。
It's possible to access (same domain) info about the parentwith the parent
global e.g. parent.document.location
, but is there a reliable way to do this cross-browser without crashing into errorswhen it detects that the parent is cross-domain?
这是可能的关于主接入(同一域)信息与parent
全球如parent.document.location
,但有一个可靠的方法来做到这一点的跨浏览器没有崩溃到错误,当它检测到的家长是跨域?
For handy testing, here's a jsbininside a jsfiddlethat crashes into an error when trying to test if parent.location.host
is accessible. Is there a reliable way to get something usable like false
telling us that this is a cross-domain parent, instead of an error?
为了方便测试,这里有一个jsfiddle 中的jsbin,它在尝试测试是否parent.location.host
可访问时会崩溃。有没有可靠的方法来获得一些可用的东西,比如false
告诉我们这是一个跨域父级,而不是一个错误?
Is there a try...catch
variant which will be robust cross-browser? Or maybe some clever trick using a return value from parent.postMessage()
? (although the parent page cannot be edited)
是否有一个try...catch
变体将是强大的跨浏览器?或者也许是一些使用返回值的聪明技巧parent.postMessage()
?(虽然不能编辑父页面)
Use case: imagine embedable content that is to be embedded on pages on its own site, and by third parties. If the page is on a same-domain iframe, we hide branding and links back to the original site because the user is already here. If they access the page from a 3rd party iframe or load the page directly, we show the branding and credits so they can see the source of the content.
用例:想象可嵌入的内容,这些内容将被嵌入到自己网站上的页面上,以及由第三方嵌入。如果页面位于同域 iframe 上,我们会隐藏品牌和链接回原始站点,因为用户已经在这里。如果他们从第 3 方 iframe 访问页面或直接加载页面,我们会显示品牌和信用,以便他们可以看到内容的来源。
To clarify, I know about the same-domain policy and I don't care whatthe cross browser domain is, I'm just looking to write a simple but reliable if
condition like if( crossDomainParent() ){ /* do something */}
澄清一下,我知道同域策略,我不在乎跨浏览器域是什么,我只是想写一个简单但可靠的if
条件,如if( crossDomainParent() ){ /* do something */}
回答by palanik
First check if you are IFramed.
首先检查您是否是IFramed。
window.self !== window.top
If you are IFramed, then your referrer is your parent frame url.
如果您是 IFramed,那么您的引荐来源网址就是您的父框架网址。
document.referrer
From this url you should be able to detect if you want to branch your code.
从这个 url 你应该能够检测到你是否想要分支你的代码。
回答by Jeff Mixon
Real cross-browser solution for posterity:
真正的跨浏览器解决方案:
function isCrossOriginFrame() {
try {
return (!window.top.location.hostname);
} catch (e) {
return true;
}
}
console.log(isCrossOriginFrame());
Tested on a decent swath of desktop and mobile browsers.
在大量桌面和移动浏览器上进行了测试。
回答by Pushker Yadav
回答by guest271314
Try this (in iframe)
试试这个(在 iframe 中)
<script type="text/javascript">
var detectOrigin = (window.location.ancestorOrigins === undefined ?
/example.com/.test(document.domain) /* firefox */ :
/example.com/.test(window.location.ancestorOrigins[0])); /* webkit */
if (detectOrigin === true) {console.log(detectOrigin)}; /* `true` example.com origin */
if (detectOrigin === false) {console.log(detectOrigin)}; /* `false` !example.com origin */
</script>
回答by N-ate
I attempted to use referer to determine cross-domain, but I discovered it was unreliable on many sites. Maybe someone will find this useful.
我尝试使用referer来确定跨域,但我发现它在许多站点上都不可靠。也许有人会发现这很有用。
function IsCrossDomainFrame() {
if( parent === window ) return false; //not a frame
var parentLocation = new URL(document.referer);//the referer of an iframe is the parent
return (parentLocation.protocol !== location.protocol ||
parentLocation.hostname !== location.hostname ||
parentLocation.port !== location.port);
}
Protocol, hostname, and port determine cross-domain.
协议、主机名和端口决定跨域。
回答by N-ate
If I see your use case:
如果我看到您的用例:
I would check it server side (who called your site), using $_SERVER['REMOTE_ADDR']
, and if it is your IP than you can hide branding and links backs.
我会检查它的服务器端(谁调用了您的站点),使用$_SERVER['REMOTE_ADDR']
,如果它是您的 IP,那么您可以隐藏品牌和链接。
If the use case is about to prevent framing your site you can use X-Frame-Options: deny
.
如果用例即将阻止构建您的网站,您可以使用X-Frame-Options: deny
.
Other guess:
Elements inside a document have a ownerDocument
property, maybe that can help detecting what you want.
其他猜测:文档中的元素有一个ownerDocument
属性,也许可以帮助检测您想要的内容。
回答by ncabral
With your current restrictions, there's no way to achieve this using the DOM API. Any evaluation with a window that belongs to another domain will spew out an error.
根据您当前的限制,无法使用 DOM API 实现这一点。任何对属于另一个域的窗口的评估都会产生错误。
However, a "hack" would be to send an XHR from your child window to load a known page in your domain. If this XHR completes successfully, then you know that both windows are the same domain.
但是,“黑客”是从您的子窗口发送 XHR 以加载您域中的已知页面。如果此 XHR 成功完成,则您知道两个窗口是同一个域。
However, this will log an error message to the console.
但是,这会将错误消息记录到控制台。
回答by Grégtheitroade Lafortune
For nested iframes : a recursive way to know if iframe (where this code is executed) is cross domain or not :
对于嵌套 iframe:一种递归方式来了解 iframe(执行此代码的位置)是否跨域:
function crosDomIfrm(win, data) {
data = (typeof data === 'undefined')?{ref:win.document.location,isCD:false}:data;
try {
if( win.document.referrer != '' ){
data.isCD = parseURL(data.ref) != parseURL(win.document.referrer);
}
} catch(e){}
if ( (win.self !== win.parent) && !data.isCD ) { //I'm in iframe
data = crosDomIfrm( win.parent, data );
}
return {ref:data.ref,isCD:data.isCD};
},
function parseURL(url) {
var a=document.createElement('a');
a.href=url;
return a.hostname;
}