3

In the past this used to work:

// 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);

However now when I try to execute this code, Firefox mentions a security error:

Error: SecurityError: The operation is insecure.

I searched the forum for an alternative and this works:

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();

But I can't access the page via getElementById

newTab.document.getElementById('hello').addEventListener("click", custom_search_function(), false);

returns:

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

How can I write to this new tab and then go back to read it through functions such as getElementById?

4

2 回答 2

2

这曾经在各种浏览器中工作了很长时间(在我过去作为 Web 开发人员的生活中,我实际上在 Web 应用程序中利用了这种技术)。过去,window.open 页面大多被视为来自与父页面相同的域(尽管行为总是有点奇怪,并且 url 栏中的 url 通常是 about:blank)。

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

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

于 2013-10-19T16:58:03.320 回答
2

You're falling foul of the Single Origin Policy. When you open a new window without a URL, by definition it can't have the same domain name as the original (opener) window.

You could instead have the window.open() call open another URL on your site (mostly blank html) and as part of its body.onload event handler (or jQuery.ready()) you could set up an event handler for the message event like this:

$(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);
}

In your originating window you call:

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

The postMessage API is now well supported across a variety of modern browsers.

You'll still not be able to directly reach in to maniuplate the content of otherWindow, but you can post messages back from otherWindow to your originating window to achieve the same effect. (e.g: put your content manipulation code in otherWindow's content and 'call' it from your originating window).

于 2013-08-10T09:50:09.530 回答