将HTML加载到页面元素中(Chrome扩展)

32

我想编写一个Chrome扩展程序,在某些网页的顶部放置一个栏。如果我的内容脚本像这样:

$('body').prepend('<div id="topbar"><h1>test</h1></div>');

一切看起来都很好,但我最终想要的是这样的:

$('body').prepend('<div id="topbar"></div>');
$('#topbar').load('topbar.html');

其中 topbar.html 是:

<h1>test</h1>

然而,当我将其更改为这个之后,网页被覆盖了。大部分内容消失了,只能看到一些广告。我甚至无法看到“test”标题。我已经检查过页面上是否有其他“topbar” id。出了什么问题?


topbar.html 文件位于哪里?是在 Chrome 扩展程序中还是网页端? - mattsven
它在Chrome扩展目录中。 - Colin
好的,.load 使用 AJAX 将文件加载到元素中,我很确定你无法通过 AJAX 加载本地 Chrome 文件。 - mattsven
2
我刚刚使用了几乎与此相同的代码。我在我的manifest.json文件中添加了“web_accessible_resources”:[...],它完美地工作了。 - Ads
4个回答

40

扩展文件夹中文件的 URL 格式如下:

chrome-extension://<ID>/topbar.html

您可以通过运行以下代码获取此路径:

chrome.extension.getURL("topbar.html")

现在如果你尝试执行:

$('#topbar').load(chrome.extension.getURL("topbar.html"));

由于跨域策略的限制,它不允许你这样做。而背景页面没有这个限制,因此您需要在那里加载HTML并将结果传递给内容脚本:

content_script.js:

chrome.extension.sendRequest({cmd: "read_file"}, function(html){
    $("#topbar").html(html);
});

background.html:

->

background.html:

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    if(request.cmd == "read_file") {
        $.ajax({
            url: chrome.extension.getURL("topbar.html"),
            dataType: "html",
            success: sendResponse
        });
    }
})

在现实世界中,你可能只会读取一次topbar.html文件,然后重复使用它。


6
$.get(chrome.extension.getURL("topbar.html"), function(topbarContent){...},'html') 这段代码对我来说很好用——我在控制台中没有看到任何跨域错误。 - Vlad Iliescu
9
在清单文件中需要指定“web_accessible_resources”。参见:http://developer.chrome.com/extensions/manifest.html#web_accessible_resources - Xiao Jia
你确定 @VladIliescu...?我的意思是... 你是以 HTML 还是某个对象的形式获取它的? - gumuruh
请注意,getURL()方法现已被弃用。根据JavaScript API的浏览器支持情况,它是“非标准的,可能会导致跨浏览器支持不佳”。 - Dony

6

12
如果你想对别人的回答进行补充,最好在他们的回答下留言,而不是另外发表一个回答。 - ChargerIIC

5

纯JS解决方案。

在您的manifest.json文件中:

{
  "manifest_version": 3,
  # [...]
  "web_accessible_resources": [{
      "matches": ["<all_urls>"],
      "resources": ["topbar.html"]
  }]
}

在你的content.js文件中:
async function load_toolbar() {
  let newElement = new DOMParser().parseFromString('<div id="toolbar"></div>', 'text/html').body.childNodes[0];
  let toolbar_url = chrome.runtime.getURL("toolbar.html");

  document.querySelector("body").appendChild(newElement);
  document.getElementById("toolbar").innerHTML = await (await fetch(toolbar_url)).text();
}

load_toolbar();

1
这是最有帮助的答案。非常好用。 - Joshua Dance

2

2020年的现在,chrome.extension.onRequest已经被弃用,加载扩展时会导致错误。 相反,应该使用chrome.runtime.sendMessage。 对于content.js,代码现在应该是:

chrome.runtime.sendMessage({cmd: "read_file"}, function(html){
    $("#topbar").html(html);
});

对于 background.js,代码现在应该是:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if(request.cmd == "read_file") {
        $.ajax({
            url: chrome.extension.getURL("topbar.html"),
            dataType: "html",
            success: sendResponse
        });
       return true;
    }
})

请确保在ajax之后注意添加'return true',这个问题曾让我困扰过。


请确保在manifest.json的web_accessible_resources中包含"topbar.html"。https://developer.chrome.com/extensions/manifest/web_accessible_resources - Satya Kalluri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接