具有src
属性的注入脚本在Chrome中异步执行。
考虑这个HTML文件:
<html><head>
<title>Chrome early script inject, Test Page</title>
<script>
var s = document.createElement ("script");
s.src = "localInject1.js";
document.documentElement.appendChild (s);
</script>
</head>
<body>
<p>See the console.</p>
<script src="localInject2.js"></script>
<script> console.log("In page: ", new Date().getTime()); </script>
</body>
</html>
localInject1.js只是:
console.log("In page's script 1: ", new Date().getTime());
和localInject2.js是:
console.log("In page's script 2: ", new Date().getTime());
名义上,控制台应显示:
In page's script 1: ...
In page's script 2: ...
In page: ...
但经常,特别是在无缓存重新加载时,您会看到:
In page's script 2: ...
In page: ...
In page's script 1: ...
设置s.async = false;
没有区别。
我不确定这是不是一个bug。 Firefox也不按顺序获取脚本,但似乎更加一致。 似乎没有任何相关的Chrome错误 ,我不清楚这些规格。
解决方法:
使用textContent
设置的代码的脚本,而不是由src
链接的文件,可以像您期望的那样立即执行。
例如,如果您将injector.js更改为:
var s = document.createElement ("script");
s.src = chrome.extension.getURL ("inject.js");
document.documentElement.appendChild (s);
var s = document.createElement ('script');
s.textContent = 'console.log ("Text runs correctly!", new Date().getTime() );';
document.documentElement.appendChild (s);
console.log("Inject finished", new Date().getTime() );
你会看到:
Text runs correctly! ...
Inject finished ...
In page
Inside inject.js
不可否认,这可能是内容脚本的一个难点,但在W3C和浏览器供应商解决此问题之前,您可以做任何事情(在Chrome中)。