GWT - 仅在Internet Explorer中设置document.domain时出现"访问被拒绝"JavaScript错误

jsp*_*ers 5 javascript subdomain iframe gwt

背景资料

我正在开发一个使用GWT(v2.4)的Web应用程序.对于应用程序,我正在创建一个iframe,它将显示来自其他网站的一些信息.我需要从那个通常通过同源策略(SOP)限制的iframe访问一些信息.但是,两个站点(父站点和iframe)都托管在同一个超级域中,只是位于不同的子域下.所以,像这样:

  • 家长:dev.app.mySite.com
  • frame:someOtherContent.mySite.com

我知道这个问题的通常解决方案是在父网站和iframe网站上设置属性:document.domain ='mySite.com'以允许SOP通过.这适用于除Internet Explorer 8(可能还有其他版本)之外的所有浏览器(我都很关注).

问题

在IE中,当我尝试加载我的Web应用程序时,我得到一个完全空白的页面,其中包含以下JS异常,"访问被拒绝".这个问题的根源在于GWT的myGwtAppName.nochache.js,其中GWT在编译过程中生成了一些代码(见下文).

从我在这个问题上所做的研究来看,这个问题的根本原因似乎是在IE中,与所有其他浏览器不同,iframe 不会继承父级的document.domain设置.根据我的理解,GWT生成的代码在iframe中运行(基于此评论:https://stackoverflow.com/a/5161888).所以,基于我对JS的有限知识,我认为发生了什么:

  1. 我通过JS在父索引页面中设置document.domain ='mySite.com'并进行处理.
  2. myGwtAppName.nochache.js已处理完毕.
  3. 在nochache.js中,运行代码来设置GWT iframe沙箱环境
  4. 在该代码中,正在对沙盒iframe的SOP受限属性进行调用
  5. 抛出异常是因为站点的父文档域已设置为"mySite.com"且iframe的document.domain未继承该设置,因此它仍然是"dev.app.mySite.com".这不会通过SOP,因为域必须完全相同.

生成的代码导致异常

下面的代码看起来像是在设置GWT沙箱iframe环境.

var $intern_4 = 'myGwtAppName',
$intern_7 = 'body',
$intern_8 = 'iframe',
$intern_9 = 'javascript:""',
$intern_10 = 'position:absolute; width:0; height:0; border:none; left: -1000px; top: -1000px; !important',
$intern_11 = '<html><head><\/head><body><\/body><\/html>',
$intern_12 = 'script',
$intern_13 = 'javascript',
$intern_14 = 'var $wnd = window.parent;''

....
....

function setupInstallLocation(){
  if (frameDoc) {
    return;
  }
  var scriptFrame = $doc.createElement($intern_8);
  scriptFrame.src = $intern_9;
  scriptFrame.id = $intern_4;
  scriptFrame.style.cssText = $intern_10;
  scriptFrame.tabIndex = -1;
  $doc.body.appendChild(scriptFrame);
  frameDoc = scriptFrame.contentDocument;
  if (!frameDoc) {
    frameDoc = scriptFrame.contentWindow.document; //THIS CAUSES THE EXCEPTION
  }
  frameDoc.open();
  frameDoc.write($intern_11);
  frameDoc.close();
  var frameDocbody = frameDoc.getElementsByTagName($intern_7)[0];
  var script = frameDoc.createElement($intern_12);
  script.language = $intern_13;
  var temp = $intern_14;
  script.text = temp;
  frameDocbody.appendChild(script);
}
....
....
Run Code Online (Sandbox Code Playgroud)

我的问题

  1. 我对这种情况的分析是完全偏离基础的吗?
  2. 有谁见过这个问题的解决方案,可以在IE的GWT环境中工作?

信息来源

IE不会继承document.domain设置:https://stackoverflow.com/a/1888711(以及许多其他线程).

GWT在iframe沙箱环境中运行:https://stackoverflow.com/a/5161888

Shu*_*ken 4

您可以使用html5 web messagingiframe 和父级之间进行通信。

请注意,Internet Explorer 存在以下错误。您只能发送字符串作为消息。您无法像其他浏览器支持那样发送对象。

如果您希望发送的不仅仅是字符串,有些人建议将对象编码为 JSON,但有时发送 URL 编码的字符串(就像 URL 中的查询字符串一样)更便宜。

以下是我的谷歌http://tutorials.jenkov.com/html5/messaging.html https://thenewcircle.com/bookshelf/html5_tutorial/messaging.html的示例 2 个最佳结果

看看他们使用不同的代码来监听消息

window.attachEvent("onmessage", handleMessage);
window.addEventListener("message", handleMessage, true);
Run Code Online (Sandbox Code Playgroud)

首先与 IE 和旧 Opera 一起工作,最后与世界其他地方一起工作。