踩坑记录:iframe获取父级页面的URL出现跨域错误

3,355 阅读1分钟

发现问题:

背景: 想在iframe页面获取父级页面的url,截取其中附带的参数

现象: iframe没有加载出来,查看控制台报错"Blocked a frame with origin XXX from accessing a cross-origin"

问题定位:

排查后发现是代码中获取父级页面的url操作导致

const parentUrl = window.parent.location.href

问题分析:

由于安全策略的影响:在父页面和iframe页面是来自不同源的情况下, parent.locationtop.location信息被认为是不安全的,无法跨源共享。
在同源的情况下可以正常访问,所以同源时不会出现跨域错误。

解决方案:

  1. 把想要获取的父页面的url参数以query的形式拼接到iframe的url上
<iframe src="http://example.com?param1=abc&param2=123"></iframe>
  1. 通过document.referrer:

<iframe>中,Document.referrer 会初始化为父窗口Window.location的href。MDN

function getParentUrl() {
    const isInIframe = (parent !== window);
    let parentUrl = null;
    if (isInIframe) {
        parentUrl = document.referrer;
    }
    return parentUrl;
}

注意:这种方式在chrome85以前可用,chrome85版本对referrer策略进行了修改,由原来默认的no-referrer-when-downgrade改为了strict-origin-when-cross-origin,即如果请求地址与请求页面非同源,将只携带请求的域名,不会再带上来源页面地址的请求参数。

解决办法:

  1. 在 HTML 内设置 referrer 策略

    • 你可以用一个namereferrer<meta> 元素为整个文档设置 referrer 策略。
       <meta name="referrer" content="no-referrer-when-downgrade"/>
    
    • 在iframe元素上用referrerpolicy 属性为其设置独立的请求策略
    <iframe src="http://example.com" referrerpolicy="no-referrer-when-downgrade">
    
  2. 设置nginx

add_header Referrer-Policy no-referrer-when-downgrade;

参考:

humanwhocodes.com/blog/2013/0…

developer.chrome.com/blog/referr…

developer.mozilla.org/zh-CN/docs/…