javascript - Firefox 扩展 : Cancel requests and emit fake responses

标签 javascript http firefox firefox-addon xpcom

我正在尝试开发一个 Firefox 扩展,它将每个 HTTP 请求丢弃到某个站点并返回一个虚假的响应。任何请求都不应到达原始 Web 服务器,但我希望能够创建自定义响应。我试图拦截“http-on-modify-request”消息,但取消请求似乎不起作用,因为之后我无法模拟真实的响应。同样,使用 nsITraceableStream 实例,我似乎无法真正取消请求。我没有想法,有人可以帮忙吗?

最佳答案

自 Firefox 21 起,以下答案已被取代,现在是 nsIHttpChannel.redirectTo() method做得很好。你可以重定向到一个数据:URI,像这样的东西会起作用:

Components.utils.import("resource://gre/modules/Services.jsm");
const Ci = Components.interfaces;

[...]

onModifyRequest: function(channel)
{
  if (channel instanceof Ci.nsIHttpChannel && shouldRedirect(channel.URI.spec))
  {
    let redirectURL = "data:text/html," + encodeURIComponent("<html>Hi there!</html>");
    channel.redirectTo(Services.io.newURI(redirectURI, null, null));
  }
}

原始答案(已过时)

每个 channel 都有其关联的 stream listener在收到数据时得到通知。伪造响应所需要做的就是获取此监听器并向其提供错误数据。和 nsITraceableChannel实际上是这样做的方法。您需要用您自己的不会执行任何操作的常规监听器替换 channel 的常用监听器,之后您可以取消该 channel 而不通知监听器。然后你触发监听器并给它你自己的数据。像这样:

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;

[...]

onModifyRequest: function(channel)
{
  if (channel instanceof Ci.nsIHttpChannel && channel instanceof Ci.nsITraceableChannel)
  {
    // Our own listener for the channel
    var fakeListener = {
      QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener,
                        Ci.nsIRequestObserver, Ci.nsIRunnable]),
      oldListener: null,
      run: function()
      {
        // Replace old listener by our fake listener
        this.oldListener = channel.setNewListener(this);

        // Now we can cancel the channel, listener old won't notice
        //channel.cancel(Components.results.NS_BINDING_ABORTED);
      },
      onDataAvailable: function(){},
      onStartRequest: function(){},
      onStopRequest: function(request, context, status)
      {
        // Call old listener with our data and set "response" headers
        var stream = Cc["@mozilla.org/io/string-input-stream;1"]
                       .createInstance(Ci.nsIStringInputStream);
        stream.setData("<html>Hi there!</html>", -1);
        this.oldListener.onStartRequest(channel, context);
        channel.setResponseHeader("Refresh", "5; url=http://google.com/", false);
        this.oldListener.onDataAvailable(channel, context, stream, 0, stream.available());
        this.oldListener.onStopRequest(channel, context, Components.results.NS_OK);
      }
    }

    // We cannot replace the listener right now, see
    // https://bugzilla.mozilla.org/show_bug.cgi?id=646370.
    // Do it asynchronously instead.
    var threadManager = Cc["@mozilla.org/thread-manager;1"]
                          .getService(Ci.nsIThreadManager);
    threadManager.currentThread.dispatch(fakeListener, Ci.nsIEventTarget.DISPATCH_NORMAL);
  }
}

此代码的问题仍然是,如果 channel 被取消,页面将显示为空白(所以我评论了那行)- 听众似乎仍在查看 channel 并注意到它已被取消。

关于javascript - Firefox 扩展 : Cancel requests and emit fake responses,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7222577/

相关文章:

http - 禁止从 dojo/request 向浏览器控制台写入错误

javascript - PHP 代码在 chrome 中返回空,在 firefox 中返回值,我该如何调查原因?

javascript - 如何使用firefox通过javascript写入本地文件

javascript - Laravel 5.6 - 选中复选框时增加数字

javascript - 叠加效果适用于 Chrome 中的 iframe 但不适用于 IE11

javascript - 使用setTimeout逐字符打印字符串

javascript - 替换图像时缩放图像以适合

javascript - 使用纯 NodeJs 放置请求

http - 使用 Deno 在本地网络上提供文件服务

windows - 您可以通过 PKCS#11 向 Mozilla Firefox 公开 Windows 证书存储吗?