在javascript中跟踪URL的重定向路径
我试图在浏览器中查找请求url的重定向数量,如果可能,我希望通过javascript跟踪该url的重定向路径 例如,如果我在浏览器中请求“A”,则假定重定向流为A->B->C->D。这意味着它会被重定向到“D”。在这种情况下,我需要得到三个301重定向状态代码和一个200 ok状态代码 我在addon.js中尝试了以下方法(并在firefox浏览器中添加了一个插件) 它是给200行(我认为这是最终的网址) 是否可以通过Javascript获得URL的所有301重定向 谢谢,有一个类型为的成员在javascript中跟踪URL的重定向路径,javascript,redirect,firefox-addon,Javascript,Redirect,Firefox Addon,我试图在浏览器中查找请求url的重定向数量,如果可能,我希望通过javascript跟踪该url的重定向路径 例如,如果我在浏览器中请求“A”,则假定重定向流为A->B->C->D。这意味着它会被重定向到“D”。在这种情况下,我需要得到三个301重定向状态代码和一个200 ok状态代码 我在addon.js中尝试了以下方法(并在firefox浏览器中添加了一个插件) 它是给200行(我认为这是最终的网址) 是否可以通过Javascript获得URL的所有301重定向 谢谢,有一个类型为的成员频道
频道
(仅可供扩展访问)。您可以将自己的回调分配给它的notificationCallbacks
属性,并实现接收重定向事件。大致如下:
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var req = new XMLHttpRequest();
req.open('GET', document.location);
var oldNotifications = req.channel.notificationCallbacks;
var oldEventSink = null;
req.channel.notificationCallbacks =
{
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsIInterfaceRequestor,
Components.interfaces.nsIChannelEventSink]),
getInterface: function(iid)
{
// We are only interested in nsIChannelEventSink, return the old callbacks
// for any other interface requests.
if (iid.equals(Ci.nsIChannelEventSink))
{
try {
oldEventSink = oldNotifications.QueryInterface(iid);
} catch(e) {}
return this;
}
if (oldNotifications)
return oldNotifications.QueryInterface(iid);
else
throw Components.results.NS_ERROR_NO_INTERFACE;
},
asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
{
var type = null;
if (flags & Components.interfaces.nsIChannelEventSink.REDIRECT_TEMPORARY)
type = "temporary";
else if (flags & Components.interfaces.nsIChannelEventSink.REDIRECT_PERMANENT)
type = "permanent";
else if (flags & Components.interfaces.nsIChannelEventSink.REDIRECT_INTERNAL)
type = "internal";
Components.utils.reportError("Redirect from " + oldChannel.URI.spec + " " +
"to " + newChannel.URI.spec + " " +
(type ? "(" + type + ")" : ""));
if (oldEventSink)
oldEventSink.asyncOnChannelRedirect(oldChannel, newChannel, flags, callback);
else
callback.onRedirectVerifyCallback(Cr.NS_OK);
}
};
req.send(null);
此代码确保在记录对nsIChannelEventSync.asyncOnChannelRedirect的任何调用时始终调用旧的通知回调
参考:,。thx,代码工作正常,但不符合预期:A->B->C->D(通道1->通道2->通道3->通道4)。
在我的例子中,它将记录a->B->C->D
的重定向链,如:
A->B(通道1->通道2),而不是B->C(通道1->通道2),C->D(通道1->通道2)
其中channel_1和channel_2
是随机散列数
所以我不能把链子连在一起。这将是捕获事件链的策略(而页面使用、元刷新、javascript、http等重定向?有趣的问题。我的直觉是,你需要在重定向链中的每个链接上创建/更新一个cookie或会话变量,因为每个重定向都构成一个新的请求,从而构成一个新的响应。这里有一些信息:你可以简单地解释一下,如何捕获重定向链中的每个链接。因为我在我的浏览器中得到了“重定向网站”(重定向链中的最后一个)的内容,并且有200个ok状态。谢谢,好极了!我只是需要这个!非常感谢。有什么方法可以阻止重定向吗?(可能我现在就要开始调查了,只是在开始之前偷懒并询问一下)ChromeWorker也可以这样做吗?@Noitidart:是的,你不必将NS\u OK传递给回调,你也可以给出isNS\u BINDING\u ABORTED
。ChromeWorker无法工作,无法访问XPCOM。谢谢!是否应该执行回调。onRedirectVerifyCallback(Components.results.NS_BINDING_ABORTED)
与我们在DXR页面上所述的抛出时不同?问是因为我可能把事情搞砸了lol@Noitidart:不太可能,它应该做同样的事情。但是,大多数错误代码将显示在错误控制台中,但是NS\u BINDING_中止
不会。谢谢@Palant,我想它之所以为我记录是因为我没有执行抛出Cr.NS_绑定
但我正在执行抛出新错误(Cr.NS_绑定_中止)
。我现在就试试。无论我在测试中做了什么,当我使用Cr.NS\u BINDING\u中止执行callback.onRedirectVerifyCallback
时,它都会致命地结束它。因此,事件不再触发,因此我的加载事件侦听器不会发生。不像我扔。这就是回调所发生的情况-“NS\u BINDING\u ABORTED:组件返回的故障代码:0x804B002(NS\u BINDING\u ABORTED)[nsAsyncVerifyRedirectCallback.onRedirectVerifyCallback”
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var req = new XMLHttpRequest();
req.open('GET', document.location);
var oldNotifications = req.channel.notificationCallbacks;
var oldEventSink = null;
req.channel.notificationCallbacks =
{
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsIInterfaceRequestor,
Components.interfaces.nsIChannelEventSink]),
getInterface: function(iid)
{
// We are only interested in nsIChannelEventSink, return the old callbacks
// for any other interface requests.
if (iid.equals(Ci.nsIChannelEventSink))
{
try {
oldEventSink = oldNotifications.QueryInterface(iid);
} catch(e) {}
return this;
}
if (oldNotifications)
return oldNotifications.QueryInterface(iid);
else
throw Components.results.NS_ERROR_NO_INTERFACE;
},
asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
{
var type = null;
if (flags & Components.interfaces.nsIChannelEventSink.REDIRECT_TEMPORARY)
type = "temporary";
else if (flags & Components.interfaces.nsIChannelEventSink.REDIRECT_PERMANENT)
type = "permanent";
else if (flags & Components.interfaces.nsIChannelEventSink.REDIRECT_INTERNAL)
type = "internal";
Components.utils.reportError("Redirect from " + oldChannel.URI.spec + " " +
"to " + newChannel.URI.spec + " " +
(type ? "(" + type + ")" : ""));
if (oldEventSink)
oldEventSink.asyncOnChannelRedirect(oldChannel, newChannel, flags, callback);
else
callback.onRedirectVerifyCallback(Cr.NS_OK);
}
};
req.send(null);