Webextension:如何透明地修改XMLHttpRequests [英] Webextension: How to transparently modify XMLHttpRequests
问题描述
我的目标
…将具有一个Web扩展(目前在Firefox中),以尽可能透明地拦截和修改站点的XMLHttpRequests问题.最好的情况是,即使明确寻找扩展名,该站点也无法检测到该扩展名.例如,我希望能够在发送关键数据之前自动对其进行编辑/替换,或者对大型图像进行高速缓存,尽管原始页面明确将其禁用.
原始方法
使用后台脚本和带有 blocking
的 browser.webRequest
来拦截所有请求.
browser.webRequest.onBeforeRequest.addListener(ModifySend,{网址:[< all_urls>"],},[阻止","requestBody"]);browser.webRequest.onResponseStarted.addListener(ModifyReceive,{网址:[< all_urls>"],},[阻止","responseHeaders"]);
这在某种程度上起作用.尽管我可以查看,但无法更改发送(POST)的内容,并且Firefox会忽略(某些?)已更改的接收标头.例如,我无法覆盖 cache-control
,原始值仍然有效.
内容脚本
因为我只对XMLHttpRequest感兴趣,所以为什么没有内容脚本按照另一个问题中的建议修改 .不幸的是,内容脚本是与运行它们的页面隔离的,并且可以检测到注入的脚本.更改响应头的问题也没有解决.
问题
拦截和修改XMLHttpRequests的正确方法是什么?有可能达到我想要的程度吗?并作为扩展:如何提供大数据blob作为响应,例如,当我不能说服浏览器忽略不缓存"标头时自己进行缓存?
最后,我使用了两种单独的方法.一种用于提供大数据blob,另一种用于 XMLHttpRequest
拦截.
内容斑点
最简单的选项似乎以将脚本插入页面.注入的脚本覆盖 XMLHttpRequest
的 open
函数:>
content.js
function injectJS(file){令D =文档;让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
中)
让realOpen = window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open = function(){let方法= arguments [0];让url = arguments [1];...realOpen.apply(this,arguments);};
My goal
… is to have a web extension (in Firefox for now) that intercepts and modified XMLHttpRequests issues by a site as transparently as possible. Best case is that the extension is undetectable by the site even when explicitly looking for it. For example, I want to be able to automatically redact/replace critical data before it is send out or enforce caching of large images despite the original page disabling that explicitly.
Original approach
Use a background script and browser.webRequest
with blocking
to intercept all requests.
browser.webRequest.onBeforeRequest.addListener(
modifySend,
{
urls: ["<all_urls>"],
},
["blocking", "requestBody"]
);
browser.webRequest.onResponseStarted.addListener(
modifyReceive,
{
urls: ["<all_urls>"],
},
["blocking", "responseHeaders"]
);
This works to some degree. While I can view all requests, changing the content of sends (POST) is not possible and (some?) changed headers of received are ignored by Firefox. For example I was not able to overwrite cache-control
, the original value was still effective.
Content scripts
Since I'm only interested in XMLHttpRequests why not have a content script modify those as suggested in another question. Unfortunately, content scripts are isolated from the page they run in and injected scripts are detectable. The problem of changing response headers is also not solved.
Questions
What is the proper way to intercept and modify XMLHttpRequests? Is it even possible to the degree I want? And as an extension: How to I provide large data blobs as a response, for example if I do my own caching when I cannot persuade the browser to ignore "no caching" headers?
In the end, I used two separate approaches. One for providing large data blobs and one for XMLHttpRequest
interception.
Content blobs
The easiest option seems to provide the data as web_accessible_resources
and then use the extension's background script to enforce redirects:
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;
}
Interception
Here I use a content script which injects a script into the page. The injected script 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 (separate file and among the 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);
};
这篇关于Webextension:如何透明地修改XMLHttpRequests的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!