【发布时间】:2016-10-12 06:39:47
【问题描述】:
我有一个应用程序在“外部”页面(不同的域等)的 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
- 我的错误报告工具报告了许多不同的浏览器,其中包括最新版本(FF 49、Android 5 上的 Chrome 43、Win 和 Android 6 上的 Chrome 53、Mobile Safari 10……)
- 因此,这似乎不是与特定浏览器或版本相关的问题。
- 500 毫秒的超时只是我选择的一个神奇数字,我认为它是完全安全的...
【问题讨论】:
-
这是在测试环境中发生的还是在野外发生的?
-
它在野外发生,我无法重现它(至少直到现在)。
-
在这种情况下,我想知道是否有些用户最终会在 iframe 之外访问您的内页,这就是消息传递不起作用的原因?您可以添加一些代码来检查内页是否在 iframe 中,快速 Google 给出了一些关于如何执行此操作的 SO 答案。
-
@DanDef 我已经进行了这样的检查,但在我原来的问题中忽略了它。我现在在上面的示例代码中添加了一些代码。查看
AppInsideIFrame.js的前几行 -
您是否尝试过将超时提高到一个非常不切实际的值?像 5000000000 之类的东西。我只是在想,如果以某种方式加载父页面的时间比您的要长,则超时可能会失败。另外,我会将您的超时设置为脚本中的最后一件事 - 添加事件并在创建超时之前发送第一个
postMessage..
标签: javascript iframe cross-domain messaging