前言
在之前的文章里,介绍了 BroadcastChannel 的广播、postMessage 的灵活以及 MessageChannel 的精准。这些现代 API 为我们提供了标准的通信能力。
今天我们要介绍下------window.name。它不是一个为通信而生的 API,但是有其独特的"跨页面持久性"特性,成为解决跨域数据传输问题的方案之一。
1. window.name是什么?
window.name 是一个极其简单的属性,它的原始设计目的是用来设置或获取窗口(浏览器标签页)的名称。
js
// 设置窗口名称
window.name = 'My Awesome Window';
// 获取窗口名称
console.log(window.name); // 'My Awesome Window'
它有一个重要的特性:
只要是在同一个浏览器标签页中,即使页面发生了跳转(从一个域名到另一个域名),
window.name的值也不会被重置,它会一直保留。 更惊人的是,它的容量非常大,通常可以达到 2MB 左右!
2. window.name 的作用域
window.name 属性是属于每一个独立的窗口上下文(Window Context的。
- 父页面 是一个窗口上下文,它有自己的
window.name。 - iframe 子页面 是另一个完全独立的窗口上下文,它也有自己 的
window.name。
它们是两个完全不同的变量,互不影响。当你在子页面中直接调用 window.name 时,你访问的是子页面自己 的 name,而不是父页面的。
2.1 如何正确访问父页面的 window.name
虽然不能直接读取,但 iframe 提供了访问父窗口的路径:window.parent,可以通过iframe.contentWindow.name设置子页面的name。
关键点: iframe 的刷新只会重置它自己 的
window.name,对父页面的window.name毫无影响。并且如果需要设置子页面的name,必须是同源。
只能读取同源子页面的name,否则会报错:

3. 实战案例
通过一个简单的例子来说明,具体看代码:
- 父页面 (
parent.html)
html
<!DOCTYPE html>
<html lang="en">
<head>
<title>父页面</title>
</head>
<body>
<h1>这是父页面</h1>
<p>父页面的 window.name: <strong id="parentName"></strong></p>
<hr>
<iframe src="child.html" id="myIframe" style="width: 100%; height: 300px; border: 1px solid black;"></iframe>
<script>
// 1. 设置父页面的 name
window.name = "我是父页面的秘密数据";
document.getElementById('parentName').textContent = window.name;
console.log('父页面: 已设置 window.name =', window.name);
</script>
</body>
</html>
- 子页面 (
child.html)
html
<!DOCTYPE html>
<html lang="en">
<head>
<title>子页面</title>
</head>
<body>
<h2>这是 iframe 子页面</h2>
<button onclick="location.reload()">刷新本页面</button>
<hr>
<p><strong>子页面自己的 window.name:</strong> <span id="childName"></span></p>
<p><strong>通过 window.parent.name 访问父页面:</strong> <span id="parentNameFromChild"></span></p>
<script>
function updateDisplay() {
// 读取子页面自己的 name
document.getElementById('childName').textContent = window.name || '(空)';
// 通过 window.parent.name 访问父页面的 name
try {
const parentName = window.parent.name;
document.getElementById('parentNameFromChild').textContent = parentName;
} catch (e) {
document.getElementById('parentNameFromChild').textContent = '访问失败 (跨域?)';
}
}
updateDisplay();
// 为了演示,我们也可以设置一下子页面自己的 name
window.name = "我是子页面自己的数据";
</script>
</body>
</html>
子页面会显示:子页面自己的 window.name: 我是子页面自己的数据,子页面会显示:通过 window.parent.name 访问父页面: 我是父页面的秘密数据。 点击"刷新本页面"按钮后 :子页面会重新加载,其自己 的 window.name 会被重置为空字符串。但是,window.parent.name 的值依然是 我是父页面的秘密数据,完全不受影响。
4. 总结
最后总结一下:window.name作为浏览器的一个老古董方案,简单了解介绍下,如果需要通讯,还是推荐postMessage等通讯方式。