[英]Foolproof way to detect if iframe is cross domain
我正在嘗試確定是否有任何 iframe 是跨域的。 根據這個問題中接受的答案: Detect when iframe is cross-domain, then bust out it says to put the code access the contentDocument
of the iframe in a try / catch
block. 我在 Chrome 中為跨域 iframe 嘗試了這個:
try {
document.getElementsByTagName('iframe')[0].contentDocument;
} catch(err){
console.log("called");
}
它仍然拋出跨域錯誤並且沒有捕獲錯誤。
我還嘗試檢查父頁面url的協議+主機+端口是否在iframe的src
中:
function thirdPartyIframe(iframe){
var url = document.location.protocol + "//" + document.location.hostname + (document.location.port === "" ? "" : ":" + document.location.port);
var regexp = new RegExp(url.replace(/\//g, "\\/").replace(/\./g, "\\."));
if (iframe.src === '' || regexp.test(iframe.src)){
return false;
} else {
return true;
}
}
但這似乎不適用於 Facebook 主頁上src
等於(很長)的第一個 iframe:
"http://www.facebook.com/ai.php?aed=AQLlH2cfdnsnLrDUVyqrQPlWpayw9N09Z_iNuhulevbeEfVa4mcVRcT8cjAZOjQb8y1QXab5Ae3aSEJx49U_Qv35rtSp1VC9cY0_CrpOjMDk40hS_Xm57A996YtRVCcWSuRZ_jZERQ_iA_E4621NAbKHT9dsB7uElkRtTvl5K-zPI0jeH-BEnlZIOXbeEdbRC6qCwoToaltolpe-Ot2KWgkfb_vBZYpzUc3jQoEHzLG6tauO9l_hkXpYpHxnt-KYFKIFZ1PgmrHgb0UcGjeKHl7yBR1AbW2n5XgdgaAhFvBjs5GZlKy566nvl8eLRA60orwkwtWYeN8-gKoAmOLm7-6minsWn8lk1h2Qn3p07HCTSnYHfv1aJ6mF5jmuzP0YYe7Ym9ZbmK-tvax4uPAQJ2OdULilKbEh8M-2V9pVY3AC228OPlrRullZuuOg8DI2A8WeMF-fbbOdOFFVCe5Gj1CaZu3LYXiqdG7mUgY6AEpk9ZzGT4fC2K8DInQo1AypCvzG64C_bEWfODeXe0aGbkWwsUUmO7E5HFg0tvZkK5IAR_xxxQ2rlf5jbcEDo_2gdIDdHe1HT75-SJLUsSA0M8EU01oNNPuWwEC2BW6inepc9QPuqeg42tcEbKLU-rIUnXDBLvgutft8azWPPQ6_LafGjCAmC9uTalagoWLLDMpQOThvPg7YeVd7qg_c9Mzn2GAfuswcxDSxyRIZo9MaOhA6mhfXeE1tmjyBBsMxnx08tO21Jsfgch59fmMxpeJzdsNMPK3FAojfglvCQ2Zrt_6ataexUB4xlM7_PhKrfBPtxb5fe2TE9-nlWruNEpoCrzI05yv4Go3CYEWHob06K_9iICfNVTFkSYGTiJnMXCy_fdgfyzUIn5QJIPRo4-Wnyg444zKAO_nyFW59LqbIanHVfFY6ybiA6KeC3meREWzTPSsrU5d_NbYHlJWb8uPNDR04jaH5e2qiYj3Y8qgLQA5m"
我的函數將其歸類為非第三方 iframe,但 Chrome 在我訪問其contentDocument
時仍會引發跨域錯誤。
我正在尋找一種萬無一失的跨瀏覽器方法來做到這一點。
您需要做的不僅僅是 try/catch 中的內容來處理不同的瀏覽器以及瀏覽器處理跨域訪問的不同方式:
function canAccessIFrame(iframe) {
var html = null;
try {
// deal with older browsers
var doc = iframe.contentDocument || iframe.contentWindow.document;
html = doc.body.innerHTML;
} catch(err){
// do nothing
}
return(html !== null);
}
在您的示例中,這將是:
var accessAllowed = canAccessIFrame(document.getElementsByTagName('iframe')[0]);
工作演示: http : //jsfiddle.net/jfriend00/XsPL6/
在 Chrome 21、Safari 5.1、Firefox 14、IE7、IE8、IE9 中測試。
適用於現代瀏覽器的更短、更易讀的函數
function canAccessIframe(iframe) {
try {
return Boolean(iframe.contentDocument);
}
catch(e){
return false;
}
}
使用 Chrome 79 和 Firefox 52 ESR 進行測試。
說明:您可以檢查任何無法跨域訪問的 iframe 屬性並轉換為布爾值。 例如:contentDocument / contentWindow.document / location.href / 等。
布爾文檔: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
這是一個較短的版本,將兩種方法與 ES6 結合在一起。 請注意,它僅在您的域和 iframe 域具有相同的安全類型時才有效。 在此示例中將 google 鏈接更改為 http,它將不起作用。
let canAccessIFrame = (iframe) => {
return !!(iframe.contentDocument)
}
let checkIFrameAccess = () => {
let result = document.getElementById('result')
let remote = canAccessIFrame(document.getElementById('remote'))
let local = canAccessIFrame(document.getElementById('local'))
result.innerHTML = `
Remote iframe access: ${remote}
<br>Local iframe access: ${local}
`
}
我用jquery這樣做了。 它可能不是 100% 整潔,但對我有用。
$(iframe).load(function (e) {
try
{
// try access to check
console.log(this.contentWindow.document);
}
catch (e)
{
console.log(e);
var messageLC = e.message.toLowerCase();
if (messageLC.indexOf("x-frame-options") > -1 || messageLC.indexOf('blocked a frame with origin') > -1 || messageLC.indexOf('accessing a cross-origin') > -1)
{
// show Error Msg with cause of cross-origin access denied
}
else
{
// Shoe Error Msg with other cause
}
}
});
在加載之前,我的 IFrame 返回一個空字符串時遇到問題。 所以我開始使用以下內容:
function canAccessIFrame(iframe) {
try {
const doc = iframe.contentDocument || iframe.contentWindow.document;
const html = doc.body.innerHTML;
return html !== null && html !== ''
} catch(err){
return false
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.