Javascript 在Firefox扩展中更改HTTP响应
如何更改Firefox扩展中的HTTP响应主体?我用下面的代码在Inspect response observer和nsIStreamListener对象上设置了http。在我获取数据、解析数据并对其进行修改后,如何将修改后的响应推回到firefox浏览器?例如,假设我在启用扩展的情况下访问Google.com,扩展应该拦截响应并将每次出现的“Google”更改为“goggle”。因此,当页面加载时,用户将看到“goggle”无处不在Javascript 在Firefox扩展中更改HTTP响应,javascript,firefox-addon,Javascript,Firefox Addon,如何更改Firefox扩展中的HTTP响应主体?我用下面的代码在Inspect response observer和nsIStreamListener对象上设置了http。在我获取数据、解析数据并对其进行修改后,如何将修改后的响应推回到firefox浏览器?例如,假设我在启用扩展的情况下访问Google.com,扩展应该拦截响应并将每次出现的“Google”更改为“goggle”。因此,当页面加载时,用户将看到“goggle”无处不在 function TmSteroidsObserver()
function TmSteroidsObserver()
{
this.register();
}
TmSteroidsObserver.prototype = {
observe: function(subject, topic, data) {
if (topic == "http-on-examine-response") {
}
else if (topic == "http-on-modify-request") {
var channel = subject.QueryInterface(Components.interfaces.nsIChannel);
var listener = new StreamListener(channel);
}
},
register: function() {
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(listener, "http-on-modify-request", false);
observerService.addObserver(listener, "http-on-examine-response", false);
},
unregister: function() {
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
observerService.removeObserver(this, "http-on-examine-response");
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_NOINTERFACE;
}
}
function StreamListener(channel) {
channel.notificationCallbacks = listener;
channel.asyncOpen(listener, null);
}
StreamListener.prototype = {
mData: "",
mChannel: null,
// nsIStreamListener
onStartRequest: function (aRequest, aContext) {
this.mData = "";
},
onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) {
var scriptableInputStream =
Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
scriptableInputStream.init(aStream);
this.mData += scriptableInputStream.read(aLength);
},
onStopRequest: function (aRequest, aContext, aStatus) {
if (Components.isSuccessCode(aStatus)) {
// request was successfull
this.mCallbackFunc(this.mData);
} else {
// request failed
this.mCallbackFunc(null);
}
this.mChannel = null;
},
// nsIChannelEventSink
onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
// if redirecting, store the new channel
this.mChannel = aNewChannel;
},
// nsIInterfaceRequestor
getInterface: function (aIID) {
try {
return this.QueryInterface(aIID);
} catch (e) {
throw Components.results.NS_NOINTERFACE;
}
},
// nsIProgressEventSink (not implementing will cause annoying exceptions)
onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
onStatus : function (aRequest, aContext, aStatus, aStatusArg) { },
// nsIHttpEventSink (not implementing will cause annoying exceptions)
onRedirect : function (aOldChannel, aNewChannel) { },
// we are faking an XPCOM interface, so we need to implement QI
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
aIID.equals(Components.interfaces.nsIChannelEventSink) ||
aIID.equals(Components.interfaces.nsIProgressEventSink) ||
aIID.equals(Components.interfaces.nsIHttpEventSink) ||
aIID.equals(Components.interfaces.nsIStreamListener))
return this;
throw Components.results.NS_NOINTERFACE;
}
};
您可以使用nsITraceableChannel截获响应 您应该根据需要修改可用的数据,并将其传递给innerListener的OnDataAvailable 下面的链接将帮助您更好地理解这一点
观察员服务只需给您的听众打电话。Firefox将接收请求、呼叫您的侦听器并发送响应。请参阅Mozilla文档 对于希望在Firefox Quantum中实现这一点的未来读者,这里有。使用长文档的方法,我能够可靠地更改(临时)插件的
background.js
中所需的内容,如下所示:
browser.webRequest.onBeforeRequest.addListener(
function fixenator(details) {
let filter = browser.webRequest.filterResponseData(details.requestId);
let decoder = new TextDecoder("utf-8");
let encoder = new TextEncoder();
let str = '';
filter.ondata = event => {
str += decoder.decode(event.data, {stream: true});
};
filter.onstop = event => {
str = str.replace(/searchPattern/g, 'replace pattern');
filter.write(encoder.encode(str));
filter.close();
}
return {};
},
{
urls: ['https://example.com/path/to/url']
//, types: ['main_frame', 'script', 'sub_frame', 'xmlhttprequest', 'other'] // optional
}
, ['blocking']
);