浏览器跨域访问iframe中的元素
正常的 iframe
aHR0cHM6Ly9jb2RlLm5oc2EuZ292LmNuL3RvU2VhcmNoLmh0bWw/c3lzZmxhZz0xMDAz
iframe 如果没有设置 src 属性,或者 src 属性的值和网站是同一个域名的,想定位 iframe 中的元素可以在浏览器中直接使用选择器进行获取。
鼠标放在标签上按右键,选择复制,选择复制 selector。
在 console 中执行document.querySelector(“body > label:nth-child(1)”).textContent 就能获取标签中的值。
跨域中的 iframe
网址 https://mail.163.com/
iframe 的 src 属性的域名和主域名不一致,存在跨域
在 console 中展开标签时, 使用正常的定位方式可以访问 iframe 中的标签。
在跑代码的过程中发现失败,然后打开浏览器,不展开 dom 树的时候,访问就会报错。
方案 1
在网上搜的方法,发现会报错,浏览器的同源策略会导致这种方式失败。
方案 2
通过消息窗口(Window Messaging)是一种在不同窗口(包括跨域窗口)之间进行通信的方法。这是一种安全的跨域通信方式,允许一个窗口向另一个窗口发送信息。
在父窗口(主域)的 HTML 文件中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Main Domain</title>
</head>
<body>
<h1>Main Domain Content</h1>
<!-- 嵌套域的 iframe -->
<iframe id="subFrame" src="https://www.sub.com/embedded-content.html" width="600" height="400" frameborder="0">
</iframe>
<script>
var subFrame = document.getElementById('subFrame');
// 添加消息事件监听器
window.addEventListener('message', function(event) {
// 检查消息来源是否是预期的域
if (event.origin === 'https://www.sub.com') {
console.log('Received message from sub iframe:', event.data);
// 处理接收到的消息
}
}, false);
// 向嵌套域 iframe 发送消息
function sendMessageToSubIframe() {
var nestedWindow = subFrame.contentWindow;
if (nestedWindow) {
// 发送消息到嵌套域 iframe
nestedWindow.postMessage('Hello from the main domain!', 'https://www.sub.com');
}
}
</script>
<button onclick="sendMessageToSubIframe()">Send Message to sub Iframe</button>
</body>
</html>
在嵌套窗口(嵌套域)的 HTML 文件中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nested Domain</title>
</head>
<body style="background-color: lightblue;">
<h2>Sub Domain Content</h2>
<script>
// 添加消息事件监听器
window.addEventListener('message', function(event) {
// 检查消息来源是否是预期的域
if (event.origin === 'https://www.main.com') {
console.log('Received message from main domain:', event.data);
// 处理接收到的消息
}
}, false);
// 向主域发送消息
function sendMessageToMainDomain() {
// 发送消息到主域
window.parent.postMessage('Hello from the sub domain!', 'https://www.main.com');
}
</script>
<button onclick="sendMessageToMainDomain()">Send Message to Main Domain</button>
</body>
</html>
通过 postMessage方法在父窗口(主域)和嵌套窗口(嵌套域)之间发送消息。通过监听 message
事件,可以在窗口接收到消息时执行相应的操作。但是这种方式适用正向开发。
最终解决
给浏览器添加参数,去除同源安全检测
–disable-web-security是Chrome浏览器的一个命令行参数,它用于在开发环境中禁用浏览器的跨域安全性策略,以方便进行跨域测试和开发。这个标志允许从一个源访问另一个源的资源,而不会触发浏览器的同源策略错误。默认是不加这个参数的,在生产环境中使用,这样会降低安全性。
运行以下命令来启动Chrome浏览器,其中包括--disable-web-security
标志:
chrome.exe --disable-web-security --user-data-dir="D:\temp"
带上参数启动浏览器,启动后浏览器会提示安全问题。
在 console 中可以正常定位标签,跑代码也没问题。