IFrame 和父级之间的跨文档消息传递问题

2024-01-21

我有一个应用程序在“外部”页面(不同域等)的 iframe 内运行。为了允许 iframe 和父级之间进行一些基本通信,我在父级页面上加载了我的一些脚本并使用postMessage进行一些跨文档消息传递。

大多数时候,这种通信会按预期进行,但有时我会看到一些错误报告给我的错误跟踪工具,但无法弄清楚它们发生的原因。

这是一些示例代码:

PluginOnParent.js

// ...
window.addEventListener('message', function(e) {
    // Check message origin etc...
    if (e.data.type === 'iFrameRequest') {
        e.source.postMessage({
            type: 'parentResponse',
            responseData: someInterestingData
        }, e.origin);
    }
    // ...
}, false);
// ...

AppInsideIFrame.js

// ...
var timeoutId;


try {
    if (window.self === window.top) {
        // We're not inside an IFrame, don't do anything...
        return;
    }
} catch (e) {
    // Browsers can block access to window.top due to same origin policy.
    // See http://stackoverflow.com/a/326076
    // If this happens, we are inside an IFrame...
}

function messageHandler(e) {
    if (e.data && (e.data.type === 'parentResponse')) {
        window.clearTimeout(timeoutId);
        window.removeEventListener('message', messageHandler);
        // Do some stuff with the sent data
    }
}

timeoutId = window.setTimeout(function() {
    errorTracking.report('Communication with parent page failed');
    window.removeEventListener('message', messageHandler);
}, 500);

window.addEventListener('message', messageHandler, false);
window.parent.postMessage({ type: 'iFrameRequest' }, '*');
// ...

当超时并报告错误时,会发生什么?

我的一些更多信息和想法:

  • 我自己无法控制父页面
  • 这似乎不是一般的“配置”问题(CORS 等),因为错误发生在大多数时间工作的同一页面上
  • 我们根本不支持 IE
  • My error reporting tool reports a multitude of different browsers amongst which are the latest versions of them (FF 49, Chrome 43 on Android 5, Chrome 53 on Win and Android 6, Mobile Safari 10, ...)
    • 因此,这似乎不是与特定浏览器或版本相关的问题。
  • 500 毫秒的超时只是我选择的一个神奇数字,我认为它是完全安全的......

问题似乎出在你的PluginOnParent.js,您将回复发送到的位置。不要使用“e.origin”(在开发人员工具中检查后返回“null”)——尝试使用文字“*”,如以下文档中所述发布消息用法(在描述中目标原点):

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

另外,作为奖励,我刚刚在两个不同的域中测试了它,它也有效。我将 Parent.html 放在一个域的 Web 服务器上,并将 iframe 的 src 更改为完全不同的域上的 child.html,它们可以很好地通信。

父级.html

<html>
<head>
    <script type="text/javascript">
        function parentInitialize() {
            window.addEventListener('message', function (e) {
                // Check message origin etc...
                if (e.data.type === 'iFrameRequest') {
                    var obj = {
                        type: 'parentResponse',
                        responseData: 'some response'
                    };
                    e.source.postMessage(obj, '*');
                }
                // ...
            })
		}
    </script>
</head>
<body style="background-color: rgb(72, 222, 218);" onload="javascript: parentInitialize();">
    <iframe src="child.html" style="width: 500px; height:350px;"></iframe>
</body>
</html>

孩子.html

<html>
<head>
    <script type="text/javascript">
        function childInitialize() {
            // ...
            var timeoutId;


            try {
                if (window.self === window.top) {
                    // We're not inside an IFrame, don't do anything...
                    return;
                }
            } catch (e) {
                // Browsers can block access to window.top due to same origin policy.
                // See http://stackoverflow.com/a/326076
                // If this happens, we are inside an IFrame...
            }

            function messageHandler(e) {
                if (e.data && (e.data.type === 'parentResponse')) {
                    window.clearTimeout(timeoutId);
                    window.removeEventListener('message', messageHandler);
                    // Do some stuff with the sent data
                    var obj = document.getElementById("status");
                    obj.value = e.data.responseData;
                }
            }

            timeoutId = window.setTimeout(function () {
                var obj = document.getElementById("status");
                obj.value = 'Communication with parent page failed';
                window.removeEventListener('message', messageHandler);
            }, 500);

            window.addEventListener('message', messageHandler, false);
            window.parent.postMessage({ type: 'iFrameRequest' }, '*');
            // ...
        }
    </script>
</head>
<body style="background-color: rgb(0, 148, 255);" onload="javascript: childInitialize();">
    <textarea type="text" style="width:400px; height:250px;" id="status" />
</body>
</html>

希望有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IFrame 和父级之间的跨文档消息传递问题 的相关文章

  • 提升变量有目的吗?

    我最近学习了很多 JavaScript 并且一直在尝试理解提升变量的值 如果有的话 我 现在 明白JS是一个两遍系统 它编译然后执行 另外 我知道 var 关键字 存在 在它声明的词法范围中 因此如果在引擎为其赋值之前调用它 那么它是 未定
  • 如何在javascript中动态向对象数组添加值?

    这是一个对象数组 var data label 1 value 12 label 1 value 12 label 1 value 12 label 1 value 12 我如何动态地为这些添加值 我尝试了以下代码但没有成功 var lab
  • appendChild 错误:无法在层次结构中的指定点插入节点

    There is an error with the function appendChild Node cannot be inserted at the specified point in the hierarchy JS var a
  • 在 JavaScript 函数中加载图像

    我有获取图像像素颜色的功能 function getImage imgsrc var img img src imgsrc var imageMap new Object img load function var canvas
  • 在自动完成上添加 jQuery 延迟

    我正在尝试为应用程序创建 jQuery 自动完成 search input on keyup function search this val autocomplete div autocomplete get ajax search se
  • 角度垫排序不适用于带点表示法的 matColumnDef

    我正在尝试按列对表进行排序 当我必须过滤另一个结果中的结果时 就会出现问题 我尝试通过括号表示法和点表示法访问该属性 但没有给出结果 还将最终节点放置在 matColumnDef 中 但失败 因为有 2 列同名 table table
  • 从对象中取出具有无效(NaN、空白等)值的键的最佳方法?

    我有一个供用户填写的简短搜索表单 将有多个搜索查询进入 MongoDB 该表单创建一个名为的变量searchParams可能看起来像这样 var searchParams city Springfield bedrooms 3 bathro
  • Rangy:插入符号下的单词(再次)

    我正在尝试创建一个预输入代码以添加到 wysihtml5 富文本编辑器 基本上 我需要能够插入人员 标签引用 例如 Twitter Github Facebook 我发现一些人试图实现同样的事情的代码 http jsfiddle net A
  • 如何按 Angular 表中的属性(该属性具有单个 rownspan)进行分组?

    我没有找到这个问题的合适标题 我的问题是 例如 我有一个包含两列的表 列汽车品牌和列汽车型号 我希望表是 like in this picture 换句话说 品牌名称只会出现 1 次 我的输入数组采用以下 json 格式 brand Aud
  • D3 向对象添加超链接?

    我正在尝试制作 D3 图 它将代表我网站的菜单 我尝试按照此处的其他指南添加超链接 但它们都不起作用 每个对象都会有一个不同的 URL 指向 主页 关于 联系方式等 如果添加超链接 我可以拖动对象吗 这意味着如果我按住单击 如果我单击该对象
  • 在 Android Chrome 中隐藏 HTML5 音频/视频通知

    我的网络应用程序上有一个 HTML5 音频元素 在某些时候 我使用以下代码以编程方式停止播放 audioElement pause audioElement currentTime 0 播放音频时 我的 Android 设备 使用 Goog
  • 在 Nodejs 中,如何停止 FOR 循环直到 MongoDB 调用返回

    我正在研究下面的代码片段 我有一个名为 stuObjList 的 JSON 对象数组 我想循环遍历数组以查找具有特定标志集的特定 JSON 对象 然后进行数据库调用以检索更多数据 当然 FOR 循环不会等待数据库调用返回并到达 j leng
  • 选择单选按钮时隐藏/显示 3 个文本框

    我有 2 个单选按钮 选择一个文本框时 我想显示 3 个文本框 并在选择其他文本框时隐藏它 这是代码 这是我的 2 个单选按钮
  • 在 React Web 应用程序中使用 createjs-soundjs

    我想用https www npmjs com package createjs soundjs https www npmjs com package createjs soundjs在 React Web 应用程序上播放声音 我正常安装了
  • Vue-Router 抽象父路由

    我正在尝试将当前网站迁移到 vuejs 站点地图必须是 login signup password reset browse search dozens of other routes 由于其中一些路线共享大量 fx 因此我将它们设为父路线
  • 如何使用 javascript 更改文件扩展名

    有谁知道在 Javascript 中更改文件扩展名的简单方法吗 例如 我有一个带有 first docx 的变量 但我需要将其更改为 first html 这将改变字符串包含文件名 let file first docx file file
  • 使用ExternalInterface和IE从JavaScript获取Flash中的当前URL

    我正在尝试获取 Flash 播放器当前所在的 URL 不是 swf 文件的 URL 而是浏览器指向的 URL 到目前为止我已经使用过 var st String ExternalInterface call window location
  • Keycloak-js updateToken(minValidity) 需要澄清

    我在Keycloak js中阅读了很多该方法的示例 但没有对以下方法进行明确的解释 updateToken minValidity number KeycloakPromise
  • Chrome 调试器注入 javascript

    我有这样的好奇心 是否可以以某种方式在我的页面中注入 javascript 并执行它并调试它 正如您在控制台中所做的那样 但在控制台中您无法暂停并观察变量 是否可以调试我通过控制台输入的代码 为什么无法调试通过 XHR 接收的代码 Than
  • $ 在 JQuery 中意味着什么

    在下面的 var obj one 1 two 2 three 3 four 4 five 5 each obj function i val console log val 这里是什么意思 是对象吗 是一个别名jQuery对象 函数 它充当

随机推荐

  • 使用 Visual Studio 2015 新模拟器调试 Cordova 应用程序 (android)

    我不确定这是我在做一些愚蠢的事情还是只是在前沿 我正在开发一个简单的 Cordova 应用程序 但这是学术性的 因为我可以使用标准的 Wizzard 生成 默认应用程序重复此问题 我让应用程序在 VS2013 上使用 Ripple 并偶尔在
  • 将全局变量传递给函数

    为什么下面的代码给我的是 0 而不是 1 我希望我的函数更改在函数外部声明的变量 但我不想在函数声明中指定该变量 that 0 function go input input go that console log that 正如 Orio
  • 从给定的物理和有效地址查找段地址

    如何从给定的数据中找到段地址 物理地址 0x119B 有效地址 0x10AB 公式可能是什么 x86 16位实模式下的有效地址只是20位的偏移量部分段 偏移量 address https thestarman pcministry com
  • 正则表达式 - 将数字与常量进行比较

    如果我想匹配所有小于 2000 的数字 我使用正则表达式 01 1 0 9 3 如果我想匹配 1 到 5 之间的所有数字 我可以使用表达式 2 4 1 但是如果我想匹配 5 到 123 之间的所有数字怎么办 有语法吗 要匹配数字 gt 5
  • 混合内容 - 不安全的样式表

    在浏览器中 我收到以下错误 混合内容 页面位于 https www website com https www website com 通过 HTTPS 加载 但请求不安全的样式表 http fonts googleapis com css
  • 使用自定义错误处理程序时如何从中止命令访问错误消息

    使用 python Flask 服务器 我希望能够使用 abort 命令抛出 http 错误响应 并在正文中使用自定义响应字符串和自定义消息 app errorhandler 400 def custom400 error response
  • Python-LDAP 无法编译[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 所以我从源代码中获得了最新的 pyt
  • Django heroku 静态目录

    我是 Heroku 的新手 我尝试了一个没有 css 的简单 django 应用程序 但我刚刚在我的应用程序中添加了一个 css 文件 当我这样做时 git push heroku master 静态文件收集失败 gt Collecting
  • 无论数据源如何,使用 Django/Django Rest Framework 验证和保存数据的正确过程是什么?

    我有一个特定的模型 我想对其执行自定义验证 我想保证在创建新实例时始终存在至少一个标识符字段 这样就不可能在没有这些字段之一的情况下创建实例 尽管没有特别需要单独的字段 from django db import models class
  • Huggingface 分类与预测作斗争

    我正在微调 longformer 然后使用进行预测TextClassificationPipeline and model inputs 方法 我不确定为什么会得到不同的结果 import pandas as pd import datas
  • 解析器未共享给依赖的 sbt 项目?

    在这个似乎涉及 xsbt web plugin 的奇怪情况下 我收到错误 unresolved dependency play play json 2 10 2 2 SNAPSHOT not found 当加载时server子项目 依赖项和
  • 使用 Validating 事件和 ErrorProvider 进行验证 - 显示错误摘要

    当我的 WinForms 中存在错误时 如何显示消息框 数据无效 尝试过类似的东西 但它不起作用 if errorprovider1 null MessageBox Show Data is invalid 也许我必须使用 bool 来解决
  • 不区分大小写的三元搜索树

    我一直在使用三元搜索树 http en wikipedia org wiki Ternary search tree有一段时间 作为数据结构来实现一个自动完成下拉组合框 这意味着 当用户输入 fo 时 将显示下拉组合框 富 食物 足球 问题
  • 线性图表中 x 轴上的多条线未显示

    我有一个单轴折线图 用户会选择year从下拉菜单中选择loan type从另一个下拉菜单 然后图表应加载 12 个月的记录annual payment and scheduled payment 两者都是线性线 仪表板 vue div cl
  • 按发布日期列出的可用.packages

    是否可以从 R 中获取 CRAN 包的发布日期 我想获取 k 个最近发布的 CRAN 软件包的列表 或者获取 dd mm yy 日期之后发布的所有软件包的列表 类似于上面的信息available packages by date html
  • 用特征名称绘制特征重要性

    在 R 中 有预先构建的函数来绘制随机森林模型的特征重要性 但在python中似乎缺少这样的方法 我在寻找一种方法matplotlib model feature importances给了我以下内容 array 2 32421835e 0
  • 查找特定 ClearCase 分支中修改的所有文件?

    有没有办法创建一个视图 为我提供在特定 ClearCase 分支中修改的所有文件的快照 例如 假设我有两个分支 product 1 0 dev product migration 1 0 dev 第二个分支被认为是升级我们的核心框架依赖项的
  • istringstream、ostringstream 和 stringstream 之间有什么区别? / 为什么不在所有情况下都使用 stringstream?

    我什么时候用std istringstream std ostringstream and std stringstream为什么我不应该使用std stringstream在每种情况下 是否存在运行时性能问题 最后 这有什么不好的地方 而
  • Springboot嵌入tomcat绑定IPV6

    我正在使用 springboot 开发rest api 当我尝试部署它自动绑定到我们不想要的ipv6的jar时 我遇到了小问题 我知道我可以使用外部tomcat 但只是为了学习 我想知道是否可以强制它绑定到 ipv4 谢谢 萨吉德 您可以使
  • IFrame 和父级之间的跨文档消息传递问题

    我有一个应用程序在 外部 页面 不同域等 的 iframe 内运行 为了允许 iframe 和父级之间进行一些基本通信 我在父级页面上加载了我的一些脚本并使用postMessage进行一些跨文档消息传递 大多数时候 这种通信会按预期进行 但