同源时直接读parent.location.origin最可靠;跨域时唯一可用的是document.referrer,需用new url解析且不可信时应fallback。

同源时直接读 parent.location.origin 最可靠
只要 iframe 与父页协议、域名、端口三者完全一致,就能安全访问 parent.location 对象。此时 parent.location.origin 是获取父页域名(含协议和端口)最简洁、无歧义的方式;若只需纯域名,可用 new URL(parent.location.href).hostname。
注意:不能依赖 parent.location.host 或 parent.location.hostname 直接取值——某些低版本 Safari 在跨子域但同主域场景下(如 a.example.com 嵌入 b.example.com),可能因策略收紧而抛出 SecurityError,哪怕实际未跨主域。
- 必须确保 iframe 已加载完成再执行,否则
parent.location可能尚未就绪 - 不要在 iframe 的
DOMContentLoaded阶段就急着读,建议监听window.onload或用parent.document.readyState === 'complete'辅助判断 - 若父页是 file:// 协议,
origin会是null,需单独 fallback
跨域时唯一可用的是 document.referrer
当 iframe 与父页不同源,浏览器会拦截对 parent.location 的任何访问,try/catch 捕获到的通常是 SecurityError: Blocked a frame with origin ...。此时无法拿到真实 URL,只能退而求其次用 document.referrer —— 它是浏览器主动透出的、受控的来源信息,不会被跨域策略阻止。
但要注意:document.referrer 不一定等于父页 URL。比如用户从搜索引擎点击进入父页、再由父页跳转进 iframe,referrer 就是搜索引擎地址;又或者父页用 location.replace() 导航,referrer 可能为空。
- 始终用
new URL(document.referrer).hostname解析,避免字符串截取出错 - 如果 referrer 为空或不可信(如
https://google.com),说明来源不可追溯,不应作为业务逻辑依据 - 不要试图用
document.referrer.match(/https?:\/\/([^\/]+)/)这类正则硬提取,遇到带端口、IPv6 或非标准协议时容易崩
用 parent !== window 判断是否嵌套,而非靠 URL 字符串
很多代码习惯用 if (window.location !== parent.location) 来检测 iframe 环境,这是错的 —— 两者的 location 对象永远不全等(即使 URL 相同),比较结果恒为 true。真正该用的是 parent !== window,它语义清晰:当前运行环境是否被其他窗口嵌套。
这个判断必须放在所有读取逻辑之前,否则在顶层页面执行 parent.location 会报错(虽然现代浏览器大多容忍,但 IE 和部分 Electron 内核仍会 throw)。
- 正确写法:
if (parent !== window) { /* 尝试读 parent.location 或 fallback 到 referrer */ } - 错误写法:
if (window.location.href !== parent.location.href)(类型不匹配且无意义) - 更糟写法:
if (parent.location)(未判空直接访问,跨域时直接 crash)
动态创建的 iframe 也要走同一套逻辑
无论是 HTML 中静态写的 <iframe src="..."></iframe>,还是 JS 动态 document.createElement('iframe') 插入的,只要加载后执行脚本,就面临同样的跨域限制。不存在“动态创建就能绕过”的例外。
唯一区别是:动态 iframe 需手动监听 load 事件才能确保子页 DOM 就绪,而静态 iframe 的脚本若写在 body 底部,常因父页未加载完 iframe 而拿不到 parent 上下文。
- 动态 iframe 示例:
iframe.addEventListener('load', () => { console.log(new URL(document.referrer).hostname); }); - 不要依赖
setTimeout等待,异步时机不可控 - 如果父页本身是 SPA,且路由变化不触发 iframe 重载,那么
document.referrer就永远停留在初始入口,这时必须由父页通过postMessage主动推送当前域名
父页面域名不是总能准确拿到的,尤其在跨域 + SPA + 动态 iframe 组合场景下,document.referrer 的局限性会被放大,这时候得靠父子约定通信机制,而不是单方面“获取”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











