javascript - 尝试在 Firefox 扩展中获取 HTTP POST 请求

标签 javascript http-headers firefox-addon

我正在构建一个扩展以在 Firefox 中获取 POST 请求。我通读了有关拦截页面加载和 HTTP 观察器的文档,但仍然无法在页面加载时获取特定的 POST 数据(例如:data1=50&sdata2=0&data3=50)。

我查看了 TamperData 的代码,发现他们使用了 stream.available() 和 stream.read(1)。但是,我无法让这些命令与我的代码一起工作。

目前我的代码是这样的:

var ObserverTest = {

observe: function(subject, topic, data) { if (topic == 'http-on-modify-request') { var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel); } if (topic == "http-on-examine-response") { var newListener = new TracingListener(); subject.QueryInterface(Ci.nsITraceableChannel); newListener.originalListener = subject.setNewListener(newListener); } }, register: function() { var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); observerService.addObserver(ObserverTest, "http-on-modify-request", false); observerService.addObserver(ObserverTest, "http-on-examine-response", false); }, unregister: function() { var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); observerService.removeObserver(ObserverTest, "http-on-modify-request"); observerService.removeObserver(ObserverTest,"http-on-examine-response"); } } window.addEventListener("load", ObserverTest.register, false); window.addEventListener("unload", ObserverTest.unregister, false); //Helper function for XPCOM instanciation (from Firebug) function CCIN(cName, ifaceName) { return Cc[cName].createInstance(Ci[ifaceName]); } // Copy response listener implementation. function TracingListener() { this.originalListener = null; this.receivedData = []; // array for incoming data. } TracingListener.prototype = { onDataAvailable: function(request, context, inputStream, offset, count) { var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream"); var storageStream = CCIN("@mozilla.org/storagestream;1", "nsIStorageStream"); var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream"); var stream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream); stream.init(binaryInputStream); binaryInputStream.setInputStream(inputStream); storageStream.init(8192, count, null); binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); // Copy received data as they come. var data = binaryInputStream.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.originalListener.onStartRequest(request, context); }, onStopRequest: function(request, context, statusCode) { // Get entire response var responseSource = this.receivedData.join(); 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; } }

最佳答案

首先,"http-on-examine-response"TracingListener根本不需要。如果你想对响应做一些事情,这个东西会有好处,但你在请求中获取数据,所以 topic == 'http-on-modify-request'是的。

以下函数(未经测试,但从我的一个扩展中复制并稍微清理了一下)演示了如何获取发布数据。假定函数是从 http-on-modify-request 调用的.

const ScriptableInputStream = Components.Constructor(
  "@mozilla.org/scriptableinputstream;1",
  "nsIScriptableInputStream",
  "init");

function observeRequest(channel, topic, data) {
  let post = null;

  if (!(channel instanceof Ci.nsIHttpChannel) ||
    !(channel instanceof Ci.nsIUploadChannel)) {
    return post;
  }
  if (channel.requestMethod !== 'POST') {
    return post;
  }

  try {
    let us = channel.uploadStream;
    if (!us) {
      return post;
    }
    if (us instanceof Ci.nsIMultiplexInputStream) {
      // Seeking in a nsIMultiplexInputStream effectively breaks the stream.
      return post;
    }
    if (!(us instanceof Ci.nsISeekableStream)) {
      // Cannot seek within the stream :(
      return post;
    }

    let oldpos = us.tell();
    us.seek(0, 0);

    try {
      let is = new ScriptableInputStream(us);

      // we'll read max 64k
      let available = Math.min(is.available(), 1 << 16);
      if (available) {
        post = is.read(available);
      }
    }
    finally {
      // Always restore the stream position!
      us.seek(0, oldpos);
    }
  }
  catch (ex) {
    Cu.reportError(ex);
  }
  return post;
}

根据您的用例,您可能想要检查 us instanceof例如nsIMIMEInputStreamnsIStringInputStream用于特殊处理或快速路径...

你可以从你的观察者那里调用它:

  observe: function(subject, topic, data) {
    if (topic == 'http-on-modify-request') {
      observeRequest(subject, topic, data);
    }
  },

关于javascript - 尝试在 Firefox 扩展中获取 HTTP POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19596310/

相关文章:

javascript - 是否有标准化的 ES6 文件扩展名?如果是这样,它是什么?

javascript - 如何在数据chart.js中插入php

performance - cookie+静态文件什么时候成为相关问题?

javascript - 帮我创建一个 Firefox 扩展(Javascript XPCOM 组件)

javascript - 在 Mozilla Add-On SDK 中使用第三方 JS 库

javascript - 在html中的两个单词之间插入空格

javascript - Play 中的子模板 JS Assets 加载顺序!框架

用于更快图像加载的 http header ?

javascript - 如何使用@angular/http中的http发送post请求

javascript - xmlhttprequest的error事件不应该有错误信息吗?