我的目标
…就是拥有一个web扩展(目前在火狐中),该扩展尽可能透明地拦截和修改XMLHttpRequests问题。最好的情况是,即使在明确查找的情况下,站点也无法检测到扩展。例如,我希望能够在发送或强制执行大型图像缓存之前自动地编辑/替换关键数据,尽管最初的页面显式禁用了这些数据。
原始方法
使用后台脚本和browser.webRequest
以及blocking
来拦截所有请求。
browser.webRequest.onBeforeRequest.addListener(
modifySend,
{
urls: ["<all_urls>"],
},
["blocking", "requestBody"]
);
browser.webRequest.onResponseStarted.addListener(
modifyReceive,
{
urls: ["<all_urls>"],
},
["blocking", "responseHeaders"]
);
这在某种程度上是可行的。虽然我可以查看所有请求,但是更改发送(POST)的内容是不可能的,而且(有些吗?)Firefox将忽略已更改的接收头。例如,我无法覆盖cache-control
,原始值仍然有效。
内容脚本
既然我只对XMLHttpRequests感兴趣,那么为什么不让一个内容脚本修改那些as suggested in another question呢?不幸的是,内容脚本是isolated from the page they run in,注入脚本是可检测的。更改响应头的问题也没有得到解决。
问题
拦截和修改XMLHttpRequests的正确方法是什么?有可能达到我想要的程度吗?作为扩展:我如何提供大数据块作为响应,例如,当我无法说服浏览器忽略“无缓存”头时,如果我自己进行缓存的话?
发布于 2020-05-01 11:59:36
最后,我使用了两种不同的方法。一个用于提供大数据块,另一个用于XMLHttpRequest
拦截。
内容泡
最简单的选项似乎是以web_accessible_resources
的形式提供数据,然后使用扩展的后台脚本强制重定向:
function serveLocally(details)
{
const localRes = browser.runtime.getManifest().web_accessible_resources;
let ret = {};
localRes.forEach(file => {
if (details.url.endsWith(file))
{
ret.redirectUrl = browser.runtime.getURL(file);
}
});
return ret;
}
截取
在这里,我使用了一个内容脚本,其中injects a script into the page。注入脚本overwrites the open
function of XMLHttpRequest
content.js
function injectJS(file) {
let D = document;
let s = D.createElement('script');
s.type = "text/javascript";
s.src = browser.runtime.getURL(file);
s.onload = function() {
s.parentNode.removeChild(s);
};
(D.head || D.documentElement).appendChild(s);
}
injectJS("inject.js");
inject.js (单独的文件和web_accessible_resources
之间)
let realOpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function() {
let method = arguments[0];
let url = arguments[1];
...
realOpen.apply(this, arguments);
};
https://stackoverflow.com/questions/61021084
复制