在javascript中跟踪URL的重定向路径

在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重定向 谢谢,有一个类型为的成员频道

我试图在浏览器中查找请求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传递给回调,你也可以给出is
NS\u BINDING\u ABORTED
。ChromeWorker无法工作,无法访问XPCOM。谢谢!是否应该执行回调。onRedirectVerifyCallback(Components.results.NS_BINDING_ABORTED)
与我们在DXR页面上所述的抛出时不同?问是因为我可能把事情搞砸了lol@Noitidart:不太可能,它应该做同样的事情。但是,大多数错误代码将显示在错误控制台中,但是
NS\u BIND‌​ING_中止
不会。谢谢@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);