如何查找document.write运行的上下文。你能解决这个谜语吗

时间:2017-01-23 09:39:59

标签: document.write

基本上我将这两行代码紧接着写在一起。:

console.log(typeof (noAdsCallback));
document.write('<sc' + 'ript type="text/javascript">console.log(typeof(noAdsCallback));</scr' + 'ipt>');

第一个记录function,第二个记录undefined

当然它比这更棘手。所以这里的设置简而言之:

我有一个所谓的广告提供者瀑布。这意味着,我尝试通过编写(使用document.write)一些特殊标记(由我的广告提供商提供给我)来加载一些广告。

如果提供商没有为我找到广告,他们会发回一个javascript-snippet,如下所示:

if (typeof(window.noAdsCallback) === "function") noAdsCallback();

此函数基本上写下一个提供程序的标记,它与第一个提供程序的标记相同,直到我到达列表的末尾。

这个系统实际上工作正常,完全按照我的意愿行事。在开始日志function中给出了两行。

除非我使用Google作为广告提供商。谷歌有不同的做法,似乎搞砸了一切。

在Google中,我无法定义fallback-JavaScript-snippet。我所能做的就是提供一个后备网址。所以这个fallback-url(因为它被加载到iframe里面的iframe里面......)将一个postMessage发送到top,然后调用相同的noAdsCallback()方法。而且这也很好。收到消息并执行正确的方法。但是,这两行已经给出了不同的结果,分别是functionundefined

下一个提供程序在返回时无法找到noAdsCallback()方法,因为它使用document.write来尝试执行它。不知何故,背景丢失了。

第一个提示:在Chrome中它可以正常工作(即两行记录function),但在FF或IE中无法正常工作。

第二个提示:只要上下文永远不会切换,它就可以正常工作,但如果通过消息传递在任何时候进行通信,那就会让人感到困惑。

第三个提示:使用下面提到的精彩postcribe库,实际上解决了问题,但在其他地方引入了新的。

第四个提示:在使用document.write之前调试window.name会给出正确的名称,所以我不是随机的iFrame。

完成思考。我知道,我知道:不要使用文件写!我知道。但是,由于Adproviders一直使用它,我被迫使用它,否则我得到它:

Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

事实上,现在我正在使用postscribe(https://github.com/krux/postscribe),它就像一个魅力,除了一个lousey提供者。而工作计划的解决方案是,只为这个糟糕的提供者使用document.write,并为所有其他人提供postcribe。但我真的想知道问题的根源是什么。

任何想法,非常感谢。

1 个答案:

答案 0 :(得分:1)

我想我现在明白了。长话短说:不要使用文档.WRITE:)

如果必须,请尝试使用postscribe。

所以事后看来这是显而易见的,因为实际上,你在读到有关document.write()的任何地方都说,write()会清除整个文档。我只是没有得到它,因为我从来没有看到它发生过,每个广告都在使用它,就像整个时间一样。此外,它似乎在Chrome上运行良好。那是怎么回事?

这就是发生的事情。只要文档是打开的,这基本上意味着在写入文档时,document.write()只是附加到流中,并且不清除文档。只要我使用document.write(),附加外国广告脚本(可能并将包含document.write()),页面就不会关闭,因此文档保持打开状态。

这就是为什么将Google添加到我的瀑布中的原因,提出了一个问题:Google将所有内容都放在了iframe中。因此,包含瀑布模型的页面只能看到iframe并说:&#34;就我而言,我已经完成了#34;并关闭文档,而事实上,谷歌仍然在它。

之后,Google没有找到广告,将postMessage发送到主页面,导致下一个提供商被使用。谁然后使用document.write()并清除所有内容。

一切吗?不是一切。请记住,当我使用Chrome时,它仍然可以使用吗?原因是,Chrome只是清除HTML但保留了Javascript。所以在Chrome上,我的Javascript-waterfall工作得很好,因为所有的JS对象仍然存在。所有其他浏览器都清除了它。

这就是它。可能没有人会读它,但如果你这样做,请使用POSTSCRIBE!现在我终于真正理解了document.write()和document.open()以及document.close(),我是一个忠实粉丝。