简体   繁体   English

扩展注入<script> tag execution order

[英]Extension-injected <script> tag execution order

I have a browser extension that does the following:我有一个浏览器扩展,它执行以下操作:

  1. Executes a content script at document_start .document_start处执行内容脚本。
  2. This content script inserts a <script> element with a src attribute of a JavaScript file in my extension.此内容脚本在我的扩展中插入一个带有 JavaScript 文件的src属性的<script>元素。
  3. This JavaScript file hooks some browser functions.这个 JavaScript 文件挂钩了一些浏览器功能。

All three of these things need to happen before any script runs on the loaded page.所有这三件事都需要在加载的页面上运行任何脚本之前发生。 To that end, I've created the following in my manifest.json :为此,我在manifest.json创建了以下内容:

  "content_scripts": [
    {
      "matches": [
        "https://example.com/*",
      ],
      "run_at": "document_start",
      "js": ["js/inject.js"]
    }
  ]

Then for inject.js :然后对于inject.js

console.log('Inject');
const scriptEl = document.createElement('script');
scriptEl.src = chrome.runtime.getURL('js/hooks.js');
(document.head || document.documentElement).appendChild(scriptEl);

In hooks.js , for now, just some debugging:hooks.js ,现在,只是一些调试:

console.log('Hooks');

Finally, on my test HTML page, I have some script as well:最后,在我的测试 HTML 页面上,我还有一些脚本:

<!DOCTYPE html>
<html>
  <head>
    <script>
      document.addEventListener('DOMContentLoaded', async (e) => {
        console.log('DOMContentLoaded');
      });
    </script>
  </head>
  <body>
    <h1>Test Page</h1>
  </body>
</html>

I'm expecting to see the following on the console, in this order:我期待在控制台上按以下顺序看到以下内容:

Inject
Hooks
DOMContentLoaded

Instead, what I see:相反,我看到的是:

Inject
DOMContentLoaded
Hooks

If I inspect the DOM with my browser's developer tools, I see that the <script src=".../js/hooks.js"></script> is inserted immediately before <head> .如果我使用浏览器的开发人员工具检查 DOM,我会看到<script src=".../js/hooks.js"></script>紧接在<head>之前插入。 This is expected by the injection method.这是注入方法所预期的。

Is there a way to get this script to execute before all other scripts?有没有办法让这个脚本在所有其他脚本之前执行?

Based on the idea from @CertainPerformance, here is a hackaround solution:基于@CertainPerformance 的想法,这里有一个 hackaround 解决方案:

console.log('Inject');

const req = new XMLHttpRequest();
req.open('GET', chrome.runtime.getURL('js/hooks.js'), false);
req.send(null);
if (req.status === 200) {
  const scriptEl = document.createElement('script');
  scriptEl.textContent = req.responseText;
  (document.head || document.documentElement).appendChild(scriptEl);
}

Nasty stuff, but gets the job done for today.讨厌的东西,但完成了今天的工作。 If anyone has a more appropriate solution, let me know!如果有人有更合适的解决方案,请告诉我!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM