我有 popup.html,当通过单击浏览器操作加载弹出窗口时,会调用 popup.js。我用
chrome.tabs.executeScript()
以编程方式注入内容脚本。我需要将一个元素附加到页面主体。如何在扩展中插入来自不同 .html 文件的 HTML 代码,因为这样维护代码要容易得多。我正在考虑在 popup.js 中访问它(是否有一些 API 调用?),然后在 code
属性中插入带有检索到的 HTML 代码字符串的内容脚本代码。
我在内容脚本中看到了一些使用
XMLHttpRequest
的方法,但是有办法避免这种情况吗?我尝试使用 chrome.fileSystem
,但那是针对 Chrome 应用程序而不是扩展程序。
正如评论中提到的,这只是向
chrome.runtime.getURL("myfile.html")
发出 GET 请求的问题,其中 "myfile.html"
是您想要的文件的相对路径(从扩展的根目录)。
您可以使用原始 XHR 来做到这一点,或者,如果您使用 jQuery,则使用
$.ajax
。
"web_accessible_resources"
中声明它。
既然你不想这样,是的,还有另一种方法(不适用于内容脚本)。
您可以使用 chrome.runtime.getPackageDirectoryEntry
获得对扩展文件的只读HTML5 文件系统 访问权限:
chrome.runtime.getPackageDirectoryEntry(function(root) {
root.getFile("myfile.html", {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
// contents are in this.result
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
});
如您所见,这比 XHR 请求复杂得多。仅当想要列出文件时,人们可能才会使用此功能。
在这种情况下,为了避免将资源发布为可访问的网络资源,我所做的就是创建一个后台脚本并监听来自内容脚本的特定消息:
// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
(async () => {
if (message.type === "gimmeHTML") {
const data = await fetch(chrome.runtime.getURL(message.url));
sendResponse(data);
}
})();
// this is needed for async listeners be able to use `sendResponse` function
return true;
});
// content.js
...
const data = await chrome.runtime.sendMessage({ type: "gimmeHTML", url: "static/index.html" });
console.log(data);
...
通过这种方式,您可以将数据检索封装在“后端”后台脚本端,并且不必担心内容脚本中可能发生的任何更改,例如您不是通过文件访问而是通过 HTTP 或其他存储方法获取数据。