javascript 警告:从异步加载的外部脚本调用 document.write() 被忽略。这是如何固定的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7811985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 01:24:00  来源:igfitidea点击:

Warning: A call to document.write() from an asynchronously-loaded external script was ignored. How is this fixed?

javascriptruby-on-railsgoogle-mapsfacebox

提问by LearningRoR

In my Ruby on Rails application I am using the Facebox pluginfor an Ajax pop up window. I have 2 pages called add_retail_stores/new.html.erband add_retail_stores/new.js. The new.jspage inherits all elements from the new.html.erbpage so it looks exactly alike. I have a Google map script on the HTML page that works as it should. But the new.jspage that pops up on my different page called add_store_prices.html.erbpage(<%= link_to add_retail_store_path, :remote => true %>)

在我的 Ruby on Rails 应用程序中,我将Facebox 插件用于 Ajax 弹出窗口。我有 2 页称为add_retail_stores/new.html.erbadd_retail_stores/new.js。该new.js页面继承了该页面的所有元素,new.html.erb因此看起来完全一样。我在 HTML 页面上有一个可以正常工作的 Google 地图脚本。但是new.js在我的不同页面上弹出的页面称为add_store_prices.html.erbpage( <%= link_to add_retail_store_path, :remote => true %>)

I get the error:

我收到错误:

Warning: A call to document.write() from an asynchronously-loaded external script was ignored. Source File: http://localhost:3000/add_store_pricesLine: 0

警告:从异步加载的外部脚本调用 document.write() 被忽略。源文件:http://localhost:3000/add_store_prices行:0

I believe because it's trying to go through 2 functions/scripts. The first one for the Facebox and then the Google script. Anyone know how to handle this error?

我相信是因为它试图通过 2 个函数/脚本。第一个用于 Facebox,然后是 Google 脚本。有谁知道如何处理这个错误?

EDIT:

编辑:

I believe the Facebox plugin is using document.writebut I am not sure where, perhaps in one of these 2 lines on my page?

我相信 Facebox 插件正在使用,document.write但我不确定在哪里,也许在我页面上的这两行之一?

new.js:

新的.js:

$.facebox('<%= escape_javascript(render :template => 'business_retail_stores/new.html') %>')
$('#facebox form').data('remote','true');

回答by Marc B

Don't use document.write. The script is being loaded asynchronously, which means it's detached from the document parsing state. There is quite literally NO WAY for the JS engine to know WHERE the document.write should be executed in the page.

不要使用 document.write。脚本是异步加载的,这意味着它与文档解析状态分离。JS 引擎几乎无法知道应该在页面中的何处执行 document.write。

The external script could load instantaneously and the document.write executes where the <script src="...">tag is, or it could hit a net.burp and load an hour later, which means the document.write gets tagged at the end of the page. It's quite literally a race condition, so JS engines will ignore document.writes from scripts loaded asynchronously.

外部脚本可以立即加载,并且 document.write 在<script src="...">标记所在的位置执行,或者它可以击中 net.burp 并在一个小时后加载,这意味着 document.write 在页面末尾被标记。这实际上是一种竞争条件,因此 JS 引擎将忽略异步加载的脚本中的 document.writes。

Convert the document.write to use regular DOM operations, guarded by a document.onloadtype handler.

将 document.write 转换为使用由document.onload类型处理程序保护的常规 DOM 操作。

回答by Norguard

If you have access to the .js file in question, your best solution is going to be to modify the "document.write()" method and replace it with whatever makes sense in order to distribute the content contained within.

如果您有权访问有问题的 .js 文件,最好的解决方案是修改“document.write()”方法并将其替换为任何有意义的方法,以便分发其中包含的内容。

The reasons for this are very well described above.

其原因在上面已经很好地描述了。

If you are using document.write to write html tags to the page:

如果您使用 document.write 将 html 标签写入页面:

document.write("<script src=...></script>");

or

或者

document.write("<img href=... />");

Consider using the same sort of asynchronous format you've already been using:

考虑使用您已经使用过的相同类型的异步格式:

// Add/Remove/Sugar these components to taste
script = document.createElement("script");
script.onload = function () { namespaced.func.init(); };    
script.src = "http://...";
document.getElementsByTagName("script")[0].parentNode.appendChild(script);

If you're looking to append DOM elements that are for the user to see and interact with, then you're better off either:

如果您希望附加供用户查看和交互的 DOM 元素,那么您最好选择:

a) Grabbing a specific containter (section/div) by id, and appending your content:

a) 通过 id 获取特定容器(section/div),并附加您的内容:

document.getElementById("price").innerHTML = "<span>.95</span>";

b) Building content off-DOM and injecting it into your container:

b) 在 DOM 之外构建内容并将其注入到您的容器中:

var frag = document.createDocumentFragment(),
    span = document.createElement("span");
span.innerText = "39.95";
frag.appendChild(span);
document.getElementById("price").appendChild(frag);

Again, Sugar to your liking.

再一次,根据你的喜好加糖。

If you DON'T have access to mod this second .js file, I'd suggest taking it up with them.

如果您无权访问 mod 这个第二个 .js 文件,我建议您与他们一起使用。

回答by Kristian Benoit

I had the same problem loading google maps with the places library. I temporarily override the write function to create a new script element in the head.

我在用地方库加载谷歌地图时遇到了同样的问题。我暂时覆盖了 write 函数以在头部创建一个新的脚本元素。

(function() {
  var docWrite = document.write;
  document.write = function(text) {
    var res = /^<script[^>]*src="([^"]*)"[^>]*><\/script>$/.exec(text);
    if (res) {
      console.log("Adding script " + res[1]);
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement("script");
      script.src = res[1];
      head.appendChild(script);
    } else {
      docWrite(text);
    }
  }
})();

Now all I have to do to load a script asynchronously is

现在我要做的就是异步加载脚本

document.write('<script src="http://maps.googleapis.com/maps/api/js?libraries=places"></script>');