我怎么读&将数据写入Firefox中的新选项卡?

时间:2013-08-10 01:43:37

标签: javascript

过去这曾经起作用:

// writing
var newTab = window.open();
newTab.document.write("<html><head><title>I'm just a tab</title></head>");
newTab.document.write("<body id='hello'>With some text on it</body>");
newTab.document.write("</html>");
newTab.document.close();

// reading what was wrote
newTab.document.getElementById('hello').addEventListener("click", custom_search_function(), false);

但是现在当我尝试执行此代码时,Firefox会提到一个安全错误:

Error: SecurityError: The operation is insecure.

我搜索了论坛以寻找替代方案,这有效:

var textOnPage = "<html><head><title>I'm just a tab</title></head><body>";
var newTab = window.open("data:text/html;charset=UTF-8," + encodeURIComponent(textOnPage));
newTab.document.close();

但我无法通过getElementById

访问该页面
newTab.document.getElementById('hello').addEventListener("click", custom_search_function(), false);

返回:

Error: TypeError: newTab.document.getElementById(...) is null

如何写入此新标签,然后返回通过getElementById等功能阅读?

2 个答案:

答案 0 :(得分:2)

你对Single Origin Policy犯规了。当您打开没有URL的新窗口时,按照定义,它不能与原始(开启者)窗口具有相同的域名。

您可以让window.open()调用在您的网站上打开另一个网址(主要是空白的html),并且作为其body.onload事件处理程序(或jQuery.ready())的一部分,您可以设置message事件的事件处理程序,如下所示:

$(document).ready(function(){
   window.addEventListener("message", receiveMessage, false);
});

function receiveMessage(evt)
{
  if (evt.origin !== "https://your-domain.here")
    return;

  // do something with evt.data
  $(document.body).append(""+evt.data);
}

在原始窗口中,您可以致电:

otherWindow.postMessage(message, "https://your-domain.here");

postMessage API现在可以在各种现代浏览器中得到很好的支持。

您仍然无法直接访问maniuplate otherWindow的内容,但您可以将消息从otherWindow发回到您的原始窗口以达到相同的效果。 (例如:将您的内容操作代码放在otherWindow的内容中,并从原始窗口中“调用”它。

答案 1 :(得分:2)

这曾经在各种浏览器中工作很长时间(在我以前作为Web开发人员的生活中,我实际上利用了这种技术用于Web应用程序)。它曾经是那个window.open页面被处理的主要是它们来自与父页面相同的域(虽然行为总是有点奇怪,url栏中的url通常是:空白)。

现在的标准是打开url来源的页面:空白,虽然我可以理解为什么简化事情是有意义的,我可以理解这打破了以前行为的原因,但问题在于about:blank不是真正的url所以标准的跨源规则应该是不同的,至少在window.open调用的情况下。

这里是否存在真正的安全威胁,允许Windows写入已打开的页面?我不这么认为,但这是可能的。最后,我不再是网络开发人员了,并不关心这些事情,但如果其他人的应用程序也破坏了我也不会感到惊讶。