You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Chrome扩展Content Script提前注入JS遇双body标签问题求助

解决Chrome扩展Content Script在document_start注入脚本的DOM冲突与全局变量访问问题

我来帮你梳理下问题的核心,然后给出具体的解决方案:

问题根源

你在document_start阶段手动创建并替换document.body的操作,会和浏览器后续自动生成的页面原生body标签冲突,导致DOM结构异常。这种错误的DOM操作同时干扰了注入脚本的全局上下文,使得页面主代码无法访问你注入的变量。

解决方案

核心思路是完全放弃手动创建/替换body元素,而是直接在document_start阶段将脚本注入到已存在的文档根节点(<html>元素)中,或者用document.write更直接地插入脚本——这两种方式都能保证脚本在页面所有原生脚本之前执行,且运行在页面的全局上下文里。

1. 修改xhook.js代码,移除错误的DOM操作

以下是两种可行的修改方案:

方案一:使用document.write注入脚本(最直接)

document_start阶段使用document.write不会覆盖页面内容,而是作为页面初始HTML的一部分被解析,能确保脚本最早执行:

document.write(`<script type="text/javascript">
// Xhook library code - v1.4.9
// ... 这里放入完整的Xhook库代码 ...

console.log('loading extension');
xhook.after(async function (request, response) {
  if (request.url.startsWith("https://example.com/")) {
    var urlParams = new URLSearchParams(window.location.search);
    try {
      const apiresponse = await fetch('https://example.com/robots.txt');
      if (apiresponse.status === 200) {
        // 注意:这里需要await获取文本内容,否则response.text会是Promise对象
        response.text = await apiresponse.text();
      } else {
        console.log('File not found. Status Code: ' + apiresponse.status);
      }
    } catch (err) {
      console.error('Fetch failed:', err);
    }
  }
});
xhook.enable();
<\/script>`);
方案二:创建script标签并插入到文档根节点

如果你更倾向于DOM操作的方式,可将脚本插入到<html>元素中(document_start阶段<html>已经存在):

var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.textContent = `
// Xhook library code - v1.4.9
// ... 这里放入完整的Xhook库代码 ...

console.log('loading extension');
xhook.after(async function (request, response) {
  if (request.url.startsWith("https://example.com/")) {
    var urlParams = new URLSearchParams(window.location.search);
    try {
      const apiresponse = await fetch('https://example.com/robots.txt');
      if (apiresponse.status === 200) {
        response.text = await apiresponse.text();
      } else {
        console.log('File not found. Status Code: ' + apiresponse.status);
      }
    } catch (err) {
      console.error('Fetch failed:', err);
    }
  }
});
xhook.enable();`;
// 插入到<html>元素中,确保脚本最早被执行
document.documentElement.appendChild(script_tag);

2. 额外修复:Xhook拦截中的异步问题

你的原代码里response.text = apiresponse.text();存在逻辑错误——apiresponse.text()返回的是Promise对象,直接赋值会导致response.text不是预期的文本内容。上面的代码用async/await修正了这个问题,确保能正确获取并设置响应文本。

为什么这样能解决问题?

  • 移除手动创建body的逻辑后,浏览器会正常生成页面原生的DOM结构,不会再出现重复body标签的问题。
  • 脚本注入到文档根节点或使用document.write,能保证脚本在页面所有原生脚本之前执行,且运行在页面的全局上下文,这样你注入的xhook等变量就能被主页面代码正常访问。

内容的提问来源于stack exchange,提问作者user9811991

火山引擎 最新活动