加载html到页面元素(chrome扩展)



我试图写一个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>

当我把它改成这个的时候,网页就乱了。大部分内容都消失了,我只能看到一些广告。我甚至看不到"测试"标题。我已经检查以确保页面上没有其他"topbar"id。怎么了?

扩展文件夹内文件的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 :

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,然后重用它。

虽然上述解决方案确实有效,但需要注意的一点是,您需要从事件处理程序返回true,以便在$之后通信端口仍然可用。Ajax调用成功。

参见下面的更多信息。https://code.google.com/p/chromium/issues/detail?id=307034

纯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();

仅供参考,现在在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',这绊倒了我

最新更新