同源时可直接操作iframe的contentdocument和contentwindow,跨域时始终为null;必须监听onload、判空、用postmessage通信,并严格校验origin。

同源时可直接操作,跨域时浏览器强制禁止 DOM 访问——这不是 bug,是 same-origin policy 的刚性限制。
同源 iframe 的 contentDocument 和 contentWindow 能用,但得等对时机
同源情况下,iframe.contentDocument 和 iframe.contentWindow 是合法入口,但它们不是“创建即可用”。常见错误是动态插入 iframe 后立刻读取,结果拿到 null 或空文档。
- 必须监听
iframe.onload(不是DOMContentLoaded),再访问contentDocument - 若 iframe 是在
connectedCallback中挂载的,确保它已插入 shadowRoot 且src已设置 - 访问前加一层判空:
if (iframe.contentDocument) { ... },避免SecurityError混淆判断 - 子页面 JS 执行环境独立,父页改不了
window属性,也注入不了全局变量
跨域 iframe 的 contentDocument 始终为 null,别试了
只要协议、域名、端口任一不同,浏览器就直接屏蔽 contentDocument 和 contentWindow。这不是延迟加载问题,是硬性策略拦截。控制台不会报错,但任何读写都会触发 SecurityError。
-
document.domain在现代浏览器中已失效,且需双方配合,不推荐 - 试图用
innerHTML注入含<iframe></iframe>的字符串(比如通过<template></template>),跨域时contentDocument仍为null - 服务端响应头如
X-Frame-Options: DENY或Content-Security-Policy: frame-ancestors 'none'会直接阻止 iframe 加载,比 DOM 访问限制更早一步
Shadow DOM 里的 iframe 会叠加一层封装,但 postMessage 不受影响
把 <iframe></iframe> append 到 shadowRoot 是合法的,但它会同时受浏览上下文隔离 + Shadow DOM 封装双重限制。样式控制和 DOM 访问变得更难,但 JS 通信层没变。
- 不能用
::part()控制<iframe></iframe>的边框或尺寸——它是替换元素,必须在 shadow 内部<style></style>里硬写 -
shadowRoot.querySelector('iframe')能拿到元素,但跨域时contentDocument仍是null -
postMessage完全可用:父页调iframe.contentWindow.postMessage(),子页监听window.addEventListener('message', ...),event.origin必须用===严格校验 - Playwright/Selenium 定位需分两步:先进 shadow host,再进
contentFrame(),一步 locator 会失败
全屏请求(requestFullscreen)必须由 iframe 内部触发,且权限配置要双写
iframeElm.requestFullscreen() 永远无效;只有子页面内部的 document.documentElement.requestFullscreen() 才可能成功。而且这个调用会被浏览器静默拦截,除非所有条件都满足。
- HTML 必须同时写
allowfullscreen和allow="fullscreen",跨域缺一不可 - 父页响应头含
Permissions-Policy: fullscreen 'none'时,HTML 属性完全失效 - 调用必须发生在用户手势内(click/keydown),不能在
load回调或setTimeout中执行 - 父页的
document.fullscreenElement永远是null,哪怕整个屏幕都被占满——全屏状态只属于子文档
真正容易被忽略的是:跨域通信不是“能发消息就行”,而是子页必须在最早时机注册 message 监听器,否则首条消息会丢失;而父页发消息前,得确认 iframe 已完成加载,不是仅仅插入 DOM。这些时机差几毫秒,就会让整个流程静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











