gpt4 book ai didi

javascript - 创建 Firefox Addon 以监视和修改 XHR 请求和响应

转载 作者:数据小太阳 更新时间:2023-10-29 05:13:55 26 4
gpt4 key购买 nike

更新:我猜主题给出了一个错误的概念,即我正在寻找一个现有的插件。这是一个自定义问题,我不想要现有的解决方案。
我希望编写(或更恰本地说,修改和现有的)插件。

这是我的要求:

  • 我希望我的插件仅适用于特定站点
  • 页面上的数据使用双向哈希编码
  • XHR 请求加载了大量信息,有时显示在动画气泡等中。
  • 我的插件的当前版本通过 XPath 解析页面表达式,解码数据,并替换它们

  • 问题出在那些显示的气泡框上在鼠标悬停事件上

  • 因此,我意识到创建一个 XHR 可能是个好主意可以监听所有数据并即时解码/编码的桥
  • 经过几次搜索,我遇到了 nsITraceableInterface[1][2][3]

只是想知道我是否在正确的道路上。如果"is",那么请提供任何可能适当的额外指示和建议;如果“否”,那么......好吧,请帮助提供正确的指示:)

谢谢,
比拼。

[1]。 https://developer.mozilla.org/en/NsITraceableChannel
[2]. http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
[3]. http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/

最佳答案

nsITraceableChannel 确实是去这里的方法。 Jan Odvarko (softwareishard.com) 和我自己 (ashita.org) 的博客文章展示了如何做到这一点。您可能还想查看 http://www.ashita.org/implementing-an-xpcom-firefox-interface-and-creating-observers/ ,但是在 XPCOM 组件中并不是真的有必要这样做。

基本步骤是:

  1. 创建实现 nsITraceableChannel 的对象原型(prototype);并创建观察者来监听 http-on-modify-request 和 http-on-examine-response
  2. 注册观察员
  3. 监听这两种请求类型的观察者将我们的 nsITraceableChannel 对象添加到监听器链中,并确保我们的 nsITC 知道链中的下一个对象
  4. nsITC 对象提供了三个回调,每个都会在适当的阶段被调用:onStartRequest、onDataAvailable 和 onStopRequest
  5. 在上面的每个回调中,我们的 nsITC 对象必须将数据传递给链中的下一个项目

下面是我编写的特定于站点的附加组件的实际代码,据我所知,它的行为与您的代码非常相似。

function TracingListener() {
//this.receivedData = [];
}

TracingListener.prototype =
{
originalListener: null,
receivedData: null, // array for incoming data.

onDataAvailable: function(request, context, inputStream, offset, count)
{
var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
var storageStream = CCIN("@mozilla.org/storagestream;1", "nsIStorageStream");
binaryInputStream.setInputStream(inputStream);
storageStream.init(8192, count, null);

var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1",
"nsIBinaryOutputStream");

binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

// Copy received data as they come.
var data = binaryInputStream.readBytes(count);
//var data = inputStream.readBytes(count);

this.receivedData.push(data);

binaryOutputStream.writeBytes(data, count);
this.originalListener.onDataAvailable(request, context,storageStream.newInputStream(0), offset, count);
},

onStartRequest: function(request, context) {
this.receivedData = [];
this.originalListener.onStartRequest(request, context);
},

onStopRequest: function(request, context, statusCode)
{
try
{
request.QueryInterface(Ci.nsIHttpChannel);

if (request.originalURI && piratequesting.baseURL == request.originalURI.prePath && request.originalURI.path.indexOf("/index.php?ajax=") == 0)
{

var data = null;
if (request.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request, context);
if (postText)
data = ((String)(postText)).parseQuery();

}
var date = Date.parse(request.getResponseHeader("Date"));
var responseSource = this.receivedData.join('');

//fix leading spaces bug
responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1");

piratequesting.ProcessRawResponse(request.originalURI.spec, responseSource, date, data);
}
}
catch (e)
{
dumpError(e);
}
this.originalListener.onStopRequest(request, context, statusCode);
},

QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Components.results.NS_NOINTERFACE;
},
readPostTextFromRequest : function(request, context) {
try
{
var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Ci.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
}

// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);

// Seek locks the file so, seek to the beginning only if necko hasn't read it yet,
// since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed).
if (ss && prevOffset == 0)
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);

return text;
}
else {
dump("Failed to Query Interface for upload stream.\n");
}
}
catch(exc)
{
dumpError(exc);
}

return null;
},
readFromStream : function(stream, charset, noClose) {

var sis = CCSV("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
sis.setInputStream(stream);

var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));

if (!noClose)
sis.close();

var text = segments.join("");
return text;
}

}


hRO = {

observe: function(request, aTopic, aData){
try {
if (typeof Cc == "undefined") {
var Cc = Components.classes;
}
if (typeof Ci == "undefined") {
var Ci = Components.interfaces;
}
if (aTopic == "http-on-examine-response") {
request.QueryInterface(Ci.nsIHttpChannel);

if (request.originalURI && piratequesting.baseURL == request.originalURI.prePath && request.originalURI.path.indexOf("/index.php?ajax=") == 0) {
var newListener = new TracingListener();
request.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = request.setNewListener(newListener);
}
}
} catch (e) {
dump("\nhRO error: \n\tMessage: " + e.message + "\n\tFile: " + e.fileName + " line: " + e.lineNumber + "\n");
}
},

QueryInterface: function(aIID){
if (typeof Cc == "undefined") {
var Cc = Components.classes;
}
if (typeof Ci == "undefined") {
var Ci = Components.interfaces;
}
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}

throw Components.results.NS_NOINTERFACE;

},
};


var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);

observerService.addObserver(hRO,
"http-on-examine-response", false);

在上面的代码中,originalListener 是我们之前在链中插入的监听器。在创建跟踪监听器时保留该信息并在所有三个回调中传递数据至关重要。否则什么都不会工作(页面甚至不会加载。Firefox 本身是链中的最后一个)。

注意:上面的代码中调用了一些函数,它们是 piratequesting 附加组件的一部分,例如:parseQuery()dumpError()

关于javascript - 创建 Firefox Addon 以监视和修改 XHR 请求和响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2141469/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com