如何通过第一个网页的JavaScript脚本遍历另一打开网页的元素
问题原因
- 同源策略限制:浏览器默认的安全机制禁止不同源的页面互相访问DOM资源,你本地打开的HTML文件走的是本地文件协议,和目标站点
fireship.io的协议、域名都不匹配,因此默认无法跨源读取目标站点的DOM,你当前拿到的实际是新窗口刚打开时的空白页DOM,并非本地first.html的元素,只是和你预期的目标站点内容不符。 - 页面加载时序问题:就算两个页面同源,调用
window.open后立刻读取document,此时目标页面还没完成网络请求和渲染,拿到的也只能是初始空白页的内容,不是加载完成的目标页面内容。
解决方案
场景1:可修改目标站点代码
如果目标站点是你自己开发的,可以在目标站点内编写遍历DOM的逻辑,通过postMessage方法将结果回传给父页面,父页面监听message事件接收数据即可,该方式完全符合浏览器安全规范。
场景2:仅本地测试使用,无法修改目标站点代码
可以临时关闭浏览器的同源安全限制进行测试,注意该模式下的浏览器不要访问任何公共站点,避免安全风险,测试完成后立即关闭。
以Mac系统的Chrome浏览器为例:
- 完全退出当前运行的Chrome
- 终端执行命令:
open -n /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir=/tmp/chrome_dev_test - 在打开的浏览器中访问你本地的first.html文件
同时需要修改你的脚本,等待目标页面加载完成后再读取DOM:
<!DOCTYPE html> <head> <meta charset="utf-8" /> <title>JavaScript stuff</title> </head> <body> <script> w = window.open('https://fireship.io/courses/javascript/beginner-js-where-to-run/'); // 等待新页面加载完成后再执行DOM读取逻辑 w.addEventListener('load', () => { const elements = w.document.querySelectorAll('*'); const count = elements.length; alert(count) elements.forEach((elem) => { console.log(elem) }); }) </script> </body> </html>
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

