你的问题太宽泛了,所以我只会概述如何做到这一点,而不是一个复制粘贴就绪的解决方案,这需要一段时间来创建,并且也会剥夺你的学习经验。
观察员
首先,插件可以在浏览器发送请求之前观察和操作 HTTP(S) 请求,您只需要实现和注册所谓的 http 观察者即可。
const {classes: Cc, instances: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm"); // for Services
var httpRequestObserver = {
observe: function(channel, topic, data) {
if (topic != "http-on-modify-request") {
return;
}
if (!(channel instanceof Ci.nsIHttpChannel)) {
return; // Not actually a http channel
}
// See nsIChannel, nsIHttpChannel and nsIURI/nsIURL
if (channel.URI.host != "www.someonlineprofiles.com") {
return;
}
doSomething(channel);
},
register: function() {
Services.obs.addObserver(this, "http-on-modify-request", false);
},
unregister: function() {
Services.obs.removeObserver(this, "http-on-modify-request");
}
};
httpObserver.register();
// When your add-on is shut down, don't forget to call httpObserver.unregister();
只在你的插件中注册一次 http 观察者:
- 如果您使用的是 SDK,则将其放入
main.js
或专用模块中。您还需要稍微重写代码并将该const .. = Components
行替换为require("chrome")
.
- 如果您正在编写 XUL 覆盖附加组件,请将其放入代码模块中。
重写帖子数据
我们仍然需要实现doSomething()
并实际重写 post 数据。http 通道通常实现nsIUploadStream
接口,上传流是当前发布数据所在的位置(如果有)。它还有一个setUploadStream()
方法,您可以使用它来完全替换上传流。
function doSomething(channel) {
if (!(channel instanceof Ci.nsIUploadStream)) {
return;
}
// construct new post data
channel.setUploadStream(newStream);
}
构建新的帖子数据将取决于您的实际需求。我在另一个答案中提供了一个工作示例,说明如何做到这一点。
如果您需要从旧的上传流中获取一些数据,您需要自己解码现有channel.uploadStream
的数据multipart/form-data
。我建议您检查 TamperData 和类似的附加组件,了解他们如何在那里做事。