Firefox扩展:取消请求并发出假响应
Firefox extension: Cancel requests and emit fake responses
我正在尝试开发一个Firefox扩展,该扩展可以将每个HTTP请求丢弃到某个站点并返回假响应。没有请求应该通过原来的web服务器,但我希望能够创建一个自定义响应。我试图拦截"http-on-modify-request"消息,但取消请求似乎不起作用,因为我无法模拟真实的响应之后。类似地,使用nsITraceableStream实例,我似乎无法真正取消请求。我想不出主意了,有人能帮帮忙吗?
下面的答案在Firefox 21中已经被取代,现在nsIHttpChannel.redirectTo()方法可以很好地完成这项工作。您可以重定向到data: 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));
}
}
原始答案(过时)
每个通道都有其关联的流侦听器,当接收到数据时,会收到通知。获取响应所需要做的就是获取此侦听器并向其提供错误的数据。nsITraceableChannel就是这样做的。您需要用您自己的不做任何事情的侦听器替换通道的常用侦听器,然后您可以取消通道而不通知侦听器。然后你触发监听器,给它你自己的数据。像这样:
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);
}
}
这段代码的问题仍然是,如果频道被取消,页面显示空白(所以我注释了那一行)—似乎侦听器仍然查看频道并注意到它被取消了。
相关文章:
- 如何将getJson的响应保存在全局变量中
- 如何使用Spring MVC将Facebook返回的响应数据保存在Java类中
- 使用angularjs向浏览器发送servlet响应(下载功能)
- MockJax没有在JavaScript应用程序中发送对我AJAX请求的响应
- 不再使用innerHTML进行AJAX响应.(代码未得到响应)
- 为什么可以't我使用了AJAX响应的一部分
- 响应动画手风琴不工作
- 如何从SeleniumWebdriver获取异步Javascript响应
- Ajax调用在Firefox中不会自动响应
- 可以在响应时隐藏iphone上的“播放”按钮以进行视频播放
- 由于响应中不存在“Access Control Allow Origin”标头,跨域请求停止工作
- 如何在 JavaScript 和 HTML 中更改对输入框的提示响应
- IIS动态HTTP响应标头
- 预期响应包含一个对象,但在angular js中得到一个数组错误
- Ajax响应转换
- 并发 jquery jsonp 响应被发送到错误的成功处理程序
- $http.post 未响应并发呼叫
- 如何使用单个ajax方法处理并发ajax响应
- 使用AJAX响应终止并发请求
- 并发AJAX请求和响应功能