real跟你侃代码 - 聊聊 判断当前窗口是否在父级窗口中运行

1,177 阅读8分钟

今天主要是在代码中看到有前辈的代码,判断当前是否是在iframe中。如果在iframe中,则给请求添加上额外信息。这是很常见的需求,也是补上了我一个平时没在意的知识碎片,看到判断的形式很有趣(文中 1.1),平时其实也没有深入的思考过这块,看到网上没有记录的特别全的,于是敲下本文和大家共同进步。💖

一、几种常见的判断方式

  1. 使用 window.parent !== window 进行比较
if (window.parent !== window) {
  // 当前窗口在嵌套的 iframe 中
} else {
  // 当前窗口在顶级窗口中
}

window.parent 是用于获取当前窗口的父级窗口对象的属性。而 window 则是指向当前窗口的全局对象。

因此,window.parent !== window 表示当前窗口与其父级窗口不相等。这通常用于判断当前窗口是否处于嵌套的 iframe 中。

例如,如果在一个 iframe 中运行这段代码,它将返回 true,因为 window.parent 指向父级窗口的全局对象,而 window 指向当前 iframe 窗口的全局对象。如果在顶级窗口中运行这段代码,它将返回 false,因为顶级窗口没有父级窗口。

这种判断可用于在不同的窗口环境中执行不同的操作,或根据当前窗口的位置来调整应用程序的行为。

  1. 使用 window.selfwindow.top 进行比较
if (window.self !== window.top) {
  // 当前窗口在嵌套的 iframe 中
} else {
  // 当前窗口在顶级窗口中
}

window.self 表示当前窗口的全局对象,而 window.top 表示顶级窗口的全局对象。通过比较这两个对象,可以确定当前窗口是否在嵌套的 iframe 中运行。

  1. 使用 window.frameElement 进行判断

    if (window.frameElement !== null) {
      // 当前窗口在嵌套的 iframe 中
    } else {
      // 当前窗口在顶级窗口中
    }
    

    window.frameElement 表示当前窗口所在的 iframe 元素。如果窗口在 iframe 中运行,则 window.frameElement 不为 null,否则为 null

这些方法都可以用于检测当前窗口是否在父级窗口中运行。根据你的需求和具体的上下文,选择适合的方法进行判断。

二、简单的示例代码

  • index.html
<!DOCTYPE html>
<html lang="en">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>Document</title>
    </head>
    <body>
        <iframe src="./inner.html"></iframe>
    </body>
</html>
  • inner.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <style>
        .demo-inner-div{
            width:500px;
            height:500px;
            background-color: red;
        }
    </style>
    <body>
        <div class="demo-inner-div"></div>
        <script>
            const isInFrame = window.parent !== window;
            const isInFrame2 = window.self !== window.top;
            const isInFrame3 = window.frameElement !== null;
            console.log(isInFrame,isInFrame2,isInFrame3);
        </script>
    </body>
</html>

三、推荐的做法

当考虑稳定性兼容性时,以下是对三种判断方式的推荐顺序:

  1. 🔱使用 window.selfwindow.top 进行比较

    这种方式是最为稳定和兼容的方法之一。window.selfwindow.top 是标准的 JavaScript 属性,几乎在所有的浏览器中都得到支持。因此,它是一个可靠的选择,并且适用于大多数情况。

  2. 使用 window.parent !== window 进行比较

    这种方式也是常见且可行的方法,但在某些情况下可能存在兼容性问题。尽管大多数现代浏览器支持这种方式,但在某些旧版本的浏览器中可能不支持。因此,如果你的应用程序需要支持较旧的浏览器,可能需要进行额外的测试和兼容性处理。

  3. 使用 window.frameElement 进行判断

    这种方式在稳定性和兼容性方面相对较弱。尽管在现代浏览器中得到了广泛支持,但在一些旧版本的浏览器中可能不被支持。此外,某些浏览器可能会对 window.frameElement 进行安全限制,从而导致无法正常使用。因此,不建议将其作为首选方法,除非你的应用程序的目标环境已经明确知道支持该功能。

总的来说,使用 window.selfwindow.top 进行比较是最推荐的方式,因为它具有较好的稳定性和广泛的兼容性。如果需要更广泛的兼容性,可以使用 window.parent !== window 进行判断。而使用 window.frameElement 进行判断则需要特别注意兼容性和安全性问题,不适合作为首选方法。

四、为何需要判断当前页面是否运行在iframe

在网页开发中,使用 JavaScript 来检查当前窗口是否在父级窗口中运行可以带来一些好处和应用场景。以下是一些常见的原因:

下面每条都很重要🎈

1. 安全性

在某些情况下,你可能希望确保你的网页只能在预期的父级窗口中运行。通过检查当前窗口是否在父级窗口中,可以增加一定的安全性,防止你的网页被其他网站或恶意注入的 iframe 所滥用。

2. 适应不同的环境

如果你的网页有多种嵌入方式,例如在顶级窗口中独立打开或作为嵌入式 iframe,你可能希望根据当前窗口的位置来调整页面的行为和样式。通过检查当前窗口是否在父级窗口中,你可以根据不同的环境做出适当的调整和优化。

3. 与父级窗口进行通信

在嵌套的 iframe 中,通过检查当前窗口是否在父级窗口中,你可以确定如何与父级窗口进行通信。你可以使用 window.postMessage 方法来与父级窗口进行安全的跨域通信,通过传递消息和数据来实现页面之间的交互和协作。

4. 控制页面行为

根据当前窗口是否在父级窗口中,你可以控制页面的某些行为和功能。例如,你可以在父级窗口中提供一些控制按钮或选项,根据当前窗口的位置来显示或隐藏这些功能。

5. 在iframe中发出请求

当在 iframe 中发出请求时,与在普通页面中发出的请求相比,可能会存在一些不同之处。以下是一些常见的不同之处:

  1. 安全策略限制:浏览器的安全策略可能会对 iframe 中的请求施加一些限制。例如,跨域请求 (Cross-Origin Requests) 可能受到同源策略的限制,只能在特定条件下进行跨域通信。

  2. Cookie 限制:在某些情况下,跨域的 iframe 请求可能无法访问父级页面的 Cookie。这是由于浏览器的安全策略所决定的。要在跨域的 iframe 请求中传递身份验证信息,可能需要使用其他机制,如在请求中包含身份验证令牌。

  3. 请求上下文差异:在 iframe 中发出的请求会在请求的上下文中包含一些额外的信息。例如,Referer 头部可能会包含父级页面的 URL,用于指示请求来自于哪个页面。

  4. 窗口环境差异:在 iframe 中发出的请求会受到所在窗口环境的限制和影响。例如,如果 iframe 的尺寸很小,可能会受到浏览器的资源限制,例如并发连接数的限制。

需要注意的是,以上是一些一般情况下的可能差异,实际情况可能因浏览器和安全策略的特殊要求而有所不同。在开发时,需要了解和考虑这些差异,并根据具体需求进行适当的处理和调整。

五、总结

今天是处暑,上海下午下了一场大雨,在工区11L,雨劈里啪啦的打在玻璃上,随着暑气散去,感觉整个人都变得更加的平静。下面是维基百科上对处暑的说明 📕

处暑,是二十四节气之一,在8月23日前后(22日~24日),斗指太阳到达黄经150°[1]。 《月令七十二候集解》:“七月中,处,止也,暑气至此而止矣。”[2]。这时的三伏天气已过或接近尾声,所以称“暑气至此而止矣”。中国有“处暑寒来”的谚语,说明夏天的暑气逐渐消退。此后中国长江以北地区气温逐渐下降。不过华南地区因为纬度较低,则仍然较为炎热,但微弱的冷空气已开始能够影响华南地区。 虽然是天气开始变冷的时间点,历书记载:“斗指戊为处暑,暑将退,伏而潜处,故名也”。所以有俗语说:争秋夺暑,是指立秋和处暑之间的时间,虽然秋季在意义上已经来临,但夏天的暑气仍然未减,这段时期的酷热天气被称作秋老虎。而中国南方、港澳和台湾最常见。 - 《维基百科》

跟身边的同学交流,他们很多甚至在盼望着中秋节和国庆,哈哈,是啊,像我上次回老家都是在6月底的端午节了。身边的各位开发都很辛苦,不算是每天如履薄冰,也算是每天战战兢兢。 愿上天保佑每个努力且善良温柔的孩(你)子(们),我们一起迎接9月。👨‍🚀🍻🤓