为什么不会这个JavaScript(使用document.open和文件撰写)工作在Internet

2019-05-12 02:59发布

我迫切需要在这一个一定的帮助。

我创建一个<script>紧密平行,并再现的问题,另一个更复杂的<script>,我已经在其他地方写的。

下面介绍一下它的作用:

  • 在页上创建一个<iframe>并插入一个<div>
  • 创建并附加一个文档到<IFRAME>,其中包含一个<SCRIPT>定义几个功能(包括一个回调函数和一个加载外部<SCRIPT>的函数使用AJAX)
  • 后者外部脚本只是给回调函数,该函数调用产生一个文件,并将其追加的函数的调用的<IFRAME>很; 这应该有效地覆盖<SCRIPT>

所涉及的三个文件分别是:

  • http://troy.onespot.com/static/document_write/index.html (主页)
  • http://troy.onespot.com/static/document_write/main.js (第一<SCRIPT>其的加载)
  • http://troy.onespot.com/static/document_write/jsonp.js (在<SCRIPT>通过jQuery的$就()方法加载)

这一切都在Firefox,Safari和Chrome浏览。 它打破了在Internet Explorer和Opera。 什么情况是,在main.js渲染()函数执行,并且所有三个警报被解雇,但在<IFRAME>不会被覆盖的文档。 我不能告诉正在创建或写入到的文档,或者如果一个人都没有。

如果我在渲染()函数的开头添加调试代码(如执行console.log(文件)),工作的浏览器似乎得到现有<IFRAME>文档的句柄,并列出下面的属性包括在内。 Internet Explorer还似乎找到某种形式的文件。 我只是不知道为什么它不会让我将其覆盖。

难道是范围的问题吗? 也许我使用document.write()的,document.open()或document.close()方法不当,以及Firefox和其他一些浏览器只是让我逃脱它?

一个可能的线索:如果我参加渲染()函数出了胆量(即,只是把它们在main.js负载()之后),这工作正常。 这表明,我认为这就是我没怎么使用document.open()等,但不论如何,到时回调()函数被执行,文档对象不可用,或已经超出了范围,或类似的东西。

这有我完全难倒,这是与即将发生的最后期限非常重要的项目。 我不是一个黑客或替代方法上面,如果它让我摆脱困境。 任何帮助或洞察力会非常感激!

的console.log()中的文档属性的列表:

ATTRIBUTE_NODE: 2
CDATA_SECTION_NODE: 4
COMMENT_NODE: 8
DOCUMENT_FRAGMENT_NODE: 11
DOCUMENT_NODE: 9
DOCUMENT_POSITION_CONTAINED_BY: 16
DOCUMENT_POSITION_CONTAINS: 8
DOCUMENT_POSITION_DISCONNECTED: 1
DOCUMENT_POSITION_FOLLOWING: 4
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32
DOCUMENT_POSITION_PRECEDING: 2
DOCUMENT_TYPE_NODE: 10
ELEMENT_NODE: 1
ENTITY_NODE: 6
ENTITY_REFERENCE_NODE: 5
NOTATION_NODE: 12
PROCESSING_INSTRUCTION_NODE: 7
TEXT_NODE: 3
URL: "http://localhost/projects/test/ajax_loader/document_write/index.html"
activeElement: HTMLBodyElement
addEventListener: function addEventListener() {
adoptNode: function adoptNode() {
alinkColor: ""
all: HTMLCollection
anchors: HTMLCollection
appendChild: function appendChild() {
applets: HTMLCollection
attributes: null
baseURI: "http://localhost/projects/test/ajax_loader/document_write/index.html"
bgColor: ""
body: HTMLBodyElement
captureEvents: function captureEvents() {
characterSet: "UTF-8"
charset: "UTF-8"
childNodes: NodeList
clear: function clear() {
cloneNode: function cloneNode() {
close: function close() {
compareDocumentPosition: function compareDocumentPosition() {
compatMode: "BackCompat"
cookie: "__gads=ID=62bb88ab20ac9451:T=1256683145:S=ALNI_Mbso-nFjAvRzYhCSwhiuaDh84G8CA"
createAttribute: function createAttribute() {
createAttributeNS: function createAttributeNS() {
createCDATASection: function createCDATASection() {
createComment: function createComment() {
createDocumentFragment: function createDocumentFragment() {
createElement: function createElement() {
createElementNS: function createElementNS() {
createEntityReference: function createEntityReference() {
createEvent: function createEvent() {
createExpression: function createExpression() {
createNSResolver: function createNSResolver() {
createNodeIterator: function createNodeIterator() {
createProcessingInstruction: function createProcessingInstruction() {
createRange: function createRange() {
createTextNode: function createTextNode() {
createTreeWalker: function createTreeWalker() {
defaultCharset: "iso-8859-1"
defaultView: DOMWindow
designMode: "off"
dir: ""
dispatchEvent: function dispatchEvent() {
doctype: null
documentElement: HTMLHtmlElement
documentURI: "http://localhost/projects/test/ajax_loader/document_write/index.html"
domain: "localhost"
elementFromPoint: function elementFromPoint() {
embeds: HTMLCollection
evaluate: function evaluate() {
execCommand: function execCommand() {
fgColor: ""
firstChild: HTMLHtmlElement
forms: HTMLCollection
getCSSCanvasContext: function getCSSCanvasContext() {
getElementById: function getElementById() {
getElementsByClassName: function getElementsByClassName() {
getElementsByName: function getElementsByName() {
getElementsByTagName: function getElementsByTagName() {
getElementsByTagNameNS: function getElementsByTagNameNS() {
getOverrideStyle: function getOverrideStyle() {
getSelection: function getSelection() {
hasAttributes: function hasAttributes() {
hasChildNodes: function hasChildNodes() {
hasFocus: function hasFocus() {
height: 150
images: HTMLCollection
implementation: DOMImplementation
importNode: function importNode() {
inputEncoding: "UTF-8"
insertBefore: function insertBefore() {
isDefaultNamespace: function isDefaultNamespace() {
isEqualNode: function isEqualNode() {
isSameNode: function isSameNode() {
isSupported: function isSupported() {
jQuery1258269389622: 2
lastChild: HTMLHtmlElement
lastModified: ""
linkColor: ""
links: HTMLCollection
localName: null
location: Location
lookupNamespaceURI: function lookupNamespaceURI() {
lookupPrefix: function lookupPrefix() {
namespaceURI: null
nextSibling: null
nodeName: "#document"
nodeType: 9
nodeValue: null
normalize: function normalize() {
open: function open() {
ownerDocument: null
parentElement: null
parentNode: null
plugins: HTMLCollection
preferredStylesheetSet: null
prefix: null
previousSibling: null
queryCommandEnabled: function queryCommandEnabled() {
queryCommandIndeterm: function queryCommandIndeterm() {
queryCommandState: function queryCommandState() {
queryCommandSupported: function queryCommandSupported() {
queryCommandValue: function queryCommandValue() {
querySelector: function querySelector() {
querySelectorAll: function querySelectorAll() {
readyState: "complete"
referrer: "http://localhost/projects/test/ajax_loader/document_write/index.html"
releaseEvents: function releaseEvents() {
removeChild: function removeChild() {
removeEventListener: function removeEventListener() {
replaceChild: function replaceChild() {
scripts: HTMLCollection
selectedStylesheetSet: null
styleSheets: StyleSheetList
textContent: null
title: " Page"
vlinkColor: ""
width: 300
write: function write() {
writeln: function writeln() {
xmlEncoding: null
xmlStandalone: false
xmlVersion: null

Answer 1:

如果我把渲染()函数出了胆量(即,只是把它们在main.js负载()之后),这工作正常。

不为我在IE8。 如果我完全失去了AJAX调用并调用render()在main.js,我得到了相同的结果。 事实上,即使我只有更换整个main.js的:

document.write('hello!');

有或没有打开文件,从来没有出现您好!

如果我把所有的时间(甚至为0),在调用render在main.js,它的工作原理。 父文件的超时,在另一方面,似乎没有被做任何事情。

这种极端的古怪通过jQuery的使用暂时插入引起<script>标签执行由在jsonp.js返回的代码。 如果你简单地调用eval上的返回值,而不必jQuery的执行它,它工作正常。

一个相关的问题,我发现缩小的Hello例子证明通过的index.html:

<body>
<iframe name="foo"></iframe>
<script>
    var idoc= frames['foo'].document;
    idoc.open();
    idoc.write('<body><script src="main.js"><\/script>');
    idoc.close();
</script>

用含有main.js:

document.write('foo');

没有书面FOO。 (内联脚本,在另一方面,被罚款。)

如果idoc.close被省略,它的工作。 如果一个额外idoc.write('bar')中的溶液,所述bar被之前写入foo中只有IE。 如果我加入这两个barclose电话,IE崩溃。

所以总结一下,有使用深层问题 document.write从本身是写一个文档内部document.write ! 尽量避免它,如果在所有可能的。 document.open可以填充从父文档的iframe一个有用的方法,但你不应该真正被需要它的子文档,在那里你可以使用自己的DOM方法里面。



Answer 2:

由于大多数人都已经涵盖,IE试图做一些简单的像时有严重的问题:

var doc = window.frames['your_frame'].document;
doc.open();
doc.write('<body><script src="external_resource.js"><\/script>');
doc.close();

详尽的搜索后,我发现这这写这表明使用JavaScript:URI方案插入内容到IFRAME文档。 我亲自测试了在FF,Chrome浏览器,Safari浏览器与当前版本,以及IE 7/8/9/10此解决方案。

从他的例子借鉴,下面在地方我上面的例子会工作,并可以用来实现你以后打算什么:

var iframe = window.frames['your_frame'];
var content = '<body><script src="external_resource.js"><\/script>';
iframe.contentWindow.contents = content;
iframe.src = 'javascript:window["contents"]';

我听说它跟旧版本的Safari浏览器的不处理的JavaScript:URI方案非常好,但我无法找到一个方法来确认为使用Safari似乎定期升级大家。 我也不知道这跑进了URI在IE字符限制的问题(因为它比其他浏览器更小),但它是值得研究的,对于那些你从一个类似问题的痛苦。



Answer 3:

最根本的问题是, 在你的IE不能做

iframe_document.open();
iframe_document.write('<script src="foo.js"><\/script>');
iframe_document.close();

一旦document.close()调用的iframe,IE浏览器似乎有停止所有JavaScript执行。 JS的线程运行的是document.close(),而foo.js HTTP请求突出,因此该文件被加载,但从来没有执行。

我还没有发现任何方式父页面知道iframe中执行脚本完全结束。 一个解决办法是使foo.js负责调用document.close()本身 - 不是很愉快,但如果你不介意改变调用的脚本,它的伎俩。

注意:你不能文件撰写(“document.close()”)到直接的iframe: 导致 IE挂硬。 但是的setTimeout(函数(){document.close()},0)似乎免疫-因为有时做了document.close()加载的脚本中。 啊。



Answer 4:

您应该加载iframe的内容与"src"属性:一个iframe的身体所使用的不支持它显示替代消息浏览器。 你是,相反,在iframe注入饱满,内联,html文件和一些浏览器会不喜欢它。 更多信息这里 。

如果你想从主文件将消息发送到iframe中有一个在一个不错的教程约翰Resig的博客 。



Answer 5:

如将一些简单:

function render(data) {
    document.body.innerHTML = data;
}

解决你的问题? 工程在IE8 / Win7的。



Answer 6:

这是奇怪的,和迈克尔·克莱伯是错误的:所有的警报上来就好了,所以这个问题是不是该脚本不执行。 它不执行。

观察以下更改main.js:

$(document).ready(function() {

  // note that render() has to be moved into the window scope
  window.render = function(data) {
    document.open();
    alert('opened');
    document.write(data);
    alert('written');
    document.close();
    alert('closed');
  }

  function load() {
    $.ajax({
      url: 'jsonp.js',
      dataType: 'script'
    });
  }

  window.callback = function(data) {
    // does not work
    render(data);

    // works
    window.data = data;
    var t = setTimeout("render(data)", 0);
  }

  load();

});


文章来源: Why won't this JavaScript (using document.open and document.write) work in Internet Explorer or Opera?