iframe的name属性必须显式声明才能使target跳转生效,否则浏览器会新开标签页;静态html需写全name,动态创建应使用ifr.name='xxx'而非setattribute;跨域时仅能通过postmessage通信。

iframe 的 name 属性必须显式声明,否则 target 跳转会失效
没设 name 的 <iframe></iframe>,哪怕 DOM 里存在,<a target="xxx"></a> 或 <form target="xxx"></form> 都无法命中,浏览器会新开标签页。这不是 bug,是规范行为——target 值必须匹配某个 frame 的 name,而非元素 ID 或 class。
常见错误写法:<iframe src="page.html"></iframe>(漏 name);或动态创建时用 setAttribute('name', 'xxx')(IE7–IE8 下不生效)。
- 静态 HTML 中,务必写全:
<iframe name="main-content" src="dashboard.html"></iframe> - 动态创建时,避免
setAttribute:改用ifr.name = 'main-content'(所有现代浏览器 + IE6+ 兼容) - 若需兼容 IE7,且必须用
document.createElement,可改用字符串方式:document.createElement('<iframe name="xxx"></iframe>')(仅 IE9– 以下有效)
window.frames['xxx'] 返回的是子窗口对象,不是 iframe 元素节点
混淆这两者会导致 DOM 操作失败。比如想改子页面标题,写 document.querySelector('iframe[name="xxx"]').document.title 是错的——querySelector 返回的是 iframe 元素,它没有 document 属性。
正确路径分两层:
- 获取 iframe 元素本身(用于控制宽高、src、样式等):
document.querySelector('iframe[name="xxx"]') - 获取子页面的 window 对象(用于调 JS、读 document、改 location):
window.frames['xxx']或document.querySelector('iframe[name="xxx"]').contentWindow - 跨域时,
window.frames['xxx'].document会抛DOMException: Blocked a frame with origin...,此时只能用postMessage
IE7–IE8 对 name 属性的赋值时机极其敏感
在 IE7–IE8 中,如果先创建 <iframe></iframe> 元素,再用 setAttribute('name', 'xxx'),后续表单提交时浏览器找不到对应 frame,仍会新开窗口。根本原因是这些旧引擎把 name 视为“创建时绑定”的元数据,运行时补写无效。
绕过方式只有两个可靠路径:
- 创建即带 name:
var ifr = document.createElement('<iframe name="upload-frame"></iframe>');(注意:此语法仅 IE9– 以下支持,IE10+ 会报错) - 更通用做法:创建后立即赋值
ifr.name = 'upload-frame',且必须在插入 DOM 前完成(插入后再赋值,IE7 仍可能不认) - 绝对不要依赖
ifr.setAttribute('name', ...)在旧 IE 中做 target 绑定
跨域 iframe 的 name 仍有作用,但操作受限
name 属性本身不受同源策略限制——跨域 iframe 依然能被 target 命中、能出现在 window.frames 列表里、也能通过 window.frames['xxx'] 访问到子窗口对象。但你能做的非常有限:
- 可以调
window.frames['xxx'].postMessage(...)发消息(需目标页监听) - 可以读
window.frames['xxx'].location.href(仅当未跳转到其他源,否则返回"about:blank") - 不能读写
window.frames['xxx'].document、.history、.localStorage等任何涉及内容的属性 - 不能用
iframe.contentDocument或iframe.contentWindow.document—— 直接报错
name 是跨域场景下唯一还能稳定使用的“通道标识”,但所有实际数据交换都得靠 postMessage 显式约定协议。别指望靠 name 绕过同源限制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











