You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

获取iframe的location.hash时出现跨域访问阻止DOMException问题求助

解决跨域访问iframe location.hash 被拦截的问题

嘿,这问题我太熟了!你碰到的是浏览器核心的同源策略安全限制——浏览器为了防止恶意页面窃取数据,严格禁止不同源的页面互相访问对方的window或DOM属性。错误提示已经说得很清楚:你的主页面(https://localhost:7002)和iframe页面不属于同源,所以直接用iFrame.contentWindow.location.hash读取hash肯定会被拦。

先帮你明确下同源的定义:协议、域名、端口三者必须完全匹配,哪怕都是localhost,端口不一样(比如主页面7002,iframe用3000),或者协议不同(一个https一个http),都会被判定为跨域。

下面给你几个实用的解决方案,按需选:


方案1:让iframe和主页面完全同源

这是最简单的解决办法——先检查iframe的src地址,确保它的协议、域名、端口和主页面(https://localhost:7002)完全一致:

  • 如果iframe的src是其他端口、不同协议,或者不同域名,赶紧改成主页面同域的地址;
  • 改成同源后,你原来的代码var urlHash = iFrame.contentWindow.location.hash;就能正常工作了。

方案2:用postMessage实现跨域通信(最常用)

如果iframe的页面没办法改成同源,那postMessage是浏览器官方推荐的跨域通信方案,安全又可靠:

第一步:在iframe页面里发送hash消息

让iframe主动把hash值发给主页面,包括页面加载时和hash变化时:

// iframe页面的代码
// 监听hash变化事件
window.addEventListener('hashchange', () => {
  // 发送消息给父页面,第二个参数指定主页面域名,更安全
  window.parent.postMessage({
    type: 'iframe-hash',
    hash: window.location.hash
  }, 'https://localhost:7002');
});

// 页面加载完成后主动发送一次初始hash
window.onload = () => {
  window.parent.postMessage({
    type: 'iframe-hash',
    hash: window.location.hash
  }, 'https://localhost:7002');
};

第二步:在主页面接收消息

在你的abc.js里添加监听,接收iframe发来的hash:

// 主页面abc.js的代码
window.addEventListener('message', (event) => {
  // 一定要验证消息来源!防止恶意网站发消息过来
  if (event.origin !== 'https://你的iframe域名:端口') return;
  
  // 判断是我们需要的hash消息
  if (event.data.type === 'iframe-hash') {
    const urlHash = event.data.hash;
    // 这里就可以处理拿到的hash值了
    console.log('拿到iframe的hash:', urlHash);
  }
});

方案3:URL参数传递初始hash(仅适用于静态场景)

如果只需要获取iframe加载时的初始hash,不需要监听变化,可以直接把hash作为参数拼到iframe的src里:
比如原来的iframe src是https://other-site.com/page#section1,改成:

<iframe src="https://other-site.com/page?initial-hash=section1" id="myIframe"></iframe>

然后在主页面直接解析这个URL参数就行,但这种方式没法跟踪hash的后续变化。


最后啰嗦一句:用postMessage的时候,一定要验证event.origin,别图方便用*,指定具体的主页面/iframe域名,能避免很多安全风险。

内容的提问来源于stack exchange,提问作者Lakmal Vithanage

火山引擎 最新活动