1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > iframe 禁止打开新窗口_打开新窗口的安全和性能问题

iframe 禁止打开新窗口_打开新窗口的安全和性能问题

时间:2023-06-08 10:17:19

相关推荐

iframe 禁止打开新窗口_打开新窗口的安全和性能问题

相信大部分同学都接到过"点击页面某个地方从新窗口打开一个页面"的需求,一般这个需求都有一下两种处理方式来完成:

1.a标签加上target="_blank"属性

2.window.open(url)

但是以上两种处理方式可能会遇到已下问题:

1. 用户账户或个人信息被盗取

2. 打开新页面后,原窗口页面出现卡顿情况

经过一顿猛操作去验证, 发现新窗口打开新页面可能出现安全问题和性能问题, 原因是Window对象的opener属性

(关于window opener属性解释摘自菜鸟教程)

废话不多说, 我们通过代码来检验

<html><head> <meta charset="utf-8"> <title>原始页面title>head><body><h1 style="color: red;" id="alert-tips">h1><a href="./target.html" target="_blank">1.target _blanka><br><a id="btn-diff" href="javascript:void(0);">2.window.opena><br><a id="btn-open" href="javascript:void(0);">3.window.open并且设置opener为nulla><br><a id="btn-iframe" href="javascript:void(0);">4.新建iframe打开a><br><a href="./target.html" target="_blank" rel="noopener">5.target _blank noopenera><p id="random-number">0.6890402854817066p><script> window.onload = function () {var randomItem = document.getElementById('random-number'),btnDiff = document.getElementById('btn-diff'),btnIframe = document.getElementById('btn-iframe'),btnOpen = document.getElementById('btn-open'); console.log('DOM READY'); btnDiff.addEventListener('click', function () {window.open('./target.html'); }); btnIframe.addEventListener('click', function () {iframeOpen('./target.html'); }); btnOpen.addEventListener('click', function () {var child = window.open('./target.html');child.opener = null; }) var setRandom = function () {randomItem.innerHTML = Math.random();setTimeout(setRandom, 10); } checkHash(); setRandom(); } window.onhashchange = checkHash; function checkHash() {if (location.hash.indexOf('#hack') >= 0) {document.getElementById('alert-tips').innerHTML = '你被HACK了啊!这个页面的地址已经变了!'; } } /** * Opens the provided url by injecting a hidden iframe that calls * window.open(), then removes the iframe from the DOM. * * @param {string} url The url to open * @param {string} [strWindowName] * @param {string} [strWindowFeatures] * @returns {Window} */ function iframeOpen(url, strWindowName, strWindowFeatures) {var iframe, iframeDoc, script, openArgs, newWin; iframe = document.createElement('iframe'); iframe.style.display = 'none'; document.body.appendChild(iframe); iframeDoc = iframe.contentDocument || iframe.contentWindow.document; openArgs = '"' + url + '"'; if (strWindowName) {openArgs += ', "' + strWindowName + '"'; } if (strWindowFeatures) {openArgs += ', "' + strWindowFeatures + '"'; } script = iframeDoc.createElement('script'); script.type = 'text/javascript'; script.text = 'window.parent = null; window.top = null;' +'window.frameElement = null; var child = window.open(' + openArgs + ');' +'child.opener = null'; iframeDoc.body.appendChild(script); newWin = iframe.contentWindow.child; document.body.removeChild(iframe); return newWin; }script>body>html>

(如上为origin.html)

<html><head> <meta charset="utf-8"><title>目标页面title>head><body><p id="content">p><script> window.onload = function(arguments) {hackOrigin(); superFunJankTime(); }; function hackOrigin() {var content = document.getElementById('content'); if (window.opener) {// console.log('window.opener', window.opener)// console.log('opener', opener)opener.location = './origin.html#hack';content.innerHTML = 'HACK成功,再看看上个TAB?'; } else {content.innerHTML = 'HACK失败。。。。'; } } function superFunJankTime() {var start = Date.now(); while (Date.now() - start < 1000); setTimeout(superFunJankTime, 1000); }script>body>html>

(如上为target.html)

经过动手尝试后,发现原来第1,2个跳转链接是可以通过window.opener.location=newUrl来重写原页面的url的, 即使与原窗口的页面不同域;利用这种方式原始页面窗口的链接就被悄悄换成钓鱼页面的地址.一般人也不会关注到url悄悄变了, 因此就会造成安全性问题.

那么, 透过上面的代码, 不难发现, 这个安全性问题可以通过3,4,5可以解决安全性问题; 但是, 如果透过3,4去发生跳转的话, 我们会发现一开始的页面上的一串鬼畜随机数,偶尔有点小卡顿;这个随机数是通过一个定时器生成的, 每隔一段时间就有一个持续循环. 这个循环在阻塞新页面本身的js线程的同时, 也阻止了opener(即打开了新页面的原始页面)里的js线程. 若这种类似的操作很多的话,原始页面的可能会卡死;

问题来了,为啥新窗口会影响原来窗口的线程呢? chrome不是每个标签页一个单独的进程吗? 进程内包含若干线程吗?

chrome确实有不同的标签页面使用不同的进程和线程, 但是有个例外, 通过a标签的target="_blank"属性, 或者window.open(url)在新窗口中打开页面, 会与原窗口共用进程和线程. 这是因为opener中含有DOM信息, 两个进程中同时hold住这个DOM信息,在多个进程下很难控制, 于是放到一个进程里面

当然, 上述的问题也有对应的解决方案: 通过a标签上添加noopener属性, 可将新打开窗口的opener置为空. 这个方案可解决除IE以外的安全问题和所有现代浏览器的性能问题

总结一下:

1.使a标签noopener属性, 将新打开的窗口opener置为空(推荐)

特点: 可解决除IE外的安全问题和所有现代浏览器的性能问题

2.window.open并设置opener为空

特点: 可解决所有除safari下的安全问题, 无法解决性能问题

varnewWindow = window.open();newWindow.opener = null;newWindow.location = 'url';newWindow.target = '_blank';

3.新建iframe中打开新窗口, 然后关掉iframe

特点: 可解决safari下的安全问题, 无法解决性能问题

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。