目标:我想开发一个 Firefox Webextension(类似于 Chrome 扩展),在加载之前检测 HTML 和 JavaScript 文件。如果这些文件中有特定内容,将被阻止,否则允许通过。
问题:无法收集具有不同域的文件内容,因为它们抛出“跨域”错误,因为缺少 Access-Control-Allow-Origin 标头。
我读了很多关于这个问题的东西,文档说,如果在 Webextension 清单中设置了权限,则不需要 Access-Control-Allow-Origin 标头。这里引用Mozilla Doc:
使用权限键为您的扩展请求特殊权限。[...] 密钥可以包含三种权限: [...] 主机权限 [...] 主机权限被指定为匹配模式,每个模式标识一组 URL,扩展程序正在为其请求额外权限. 额外的特权包括:XHR 访问 这些来源[...]
我的清单.json:
{
[...],
"permissions": [
"tabs",
"*://*/*",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
"background": {
"scripts": ["backgroundscript.js"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["/lib/jquery-2.2.4.min.js", "/contentscript.js"],
"run_at": "document_start"
}
]
}
在这里,我在权限键中有“*://*/*”,这意味着每个网络资源都应该有权限并且不应该发生跨域错误?还是我错了?谁能告诉我,为什么我会收到错误或如何避免它?
我的背景脚本.js:
chrome.webRequest.onBeforeRequest.addListener(
logURL,
{urls: ["<all_urls>"], types: ["main_frame", "script"]},
["blocking"]
);
function logURL(requestDetails) {
chrome.tabs.sendMessage(
requestDetails.tabId,
{action: "getContentByURL", url: requestDetails.url, type: requestDetails.type},
function(response) {
console.log(response);
}
);
if(requestDetails.type == 'script') {
// here will be the conditions, based on the content of the files,
// if they will be canceled or allowed to pass
// actually, there is just a dummy "false"
return {cancel: false};
}
}
我的 contentscript.js:
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
var contentAll = [];
if(message.action == 'getContentByURL') {
var pageContent = getContentByURL(message.url);
contentAll.push(pageContent);
sendResponse({"content" : contentAll});
}
}
);
function getContentByURL(url) {
$(document).ready(function() {
$.get(url, function(data) {
console.log(data);
});
});
}
在 contentscript.js 中,我使用 jQuery $.get方法来访问网站内容。我还尝试了 $.ajax和 dataType jsonp,但在这种情况下,我得到了一个无限的访问链,并且脚本尝试无限次加载资源。我完全不明白,为什么会这样,可能是因为我使用了 chrome.webRequest.onBeforeRequest 监听器,如果出现新的连接就会被访问,在这种情况下它会陷入死循环?
在我阅读的Mozilla Doc中,chrome.webRequest.onBeforeRequest 有一个参数 requestBody:
包含 HTTP 请求正文数据。[...] 1. Firefox 不支持“requestBody”选项。
- 这个解决方案将是最好的 => 但它不可用
- 我用权限模式尝试了 $.get => 我得到了 Cross-Origin 错误
- 我用 jsonp 和相同的权限模式尝试了 $.ajax => 我得到了无限循环
所以问题又来了:我如何访问不同域的文件内容而不会出现跨域错误,其中域名是打开的(模式如“*://*/*”)?