【问题标题】:Tracking the redirection path of URLs in javascript在javascript中跟踪URL的重定向路径
【发布时间】:2012-06-26 12:06:28
【问题描述】:

我正在尝试在浏览器中查找请求的 url 的重定向次数,如果可能的话,我想通过 javascript 跟踪该 URL 的重定向路径。

例如,如果我在浏览器中请求“A”。假设重定向流程为 A->B->C->D。意味着,它被重定向到'D'。在这种情况下,我需要获得三个 301 重定向状态代码和一个 200 ok 状态代码。

我在我的 addon.js 中尝试了以下方法(并为 firefox 浏览器做了一个插件)。

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
var StatusValue = req.status;

它给出了 200 ok(我认为它是最终 url)。

是否可以通过 Javascript 获取 URL 的所有 301 重定向。

谢谢,

【问题讨论】:

标签: javascript redirect firefox-addon


【解决方案1】:

nsIXMLHttpRequest interface 有一个channel 类型的成员nsIChannel(仅限扩展访问)。您可以将自己的回调分配给其notificationCallbacks 属性并实现nsIChannelEventSync interface 以接收重定向事件。大致如下:

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 的任何调用时始终调用旧的通知回调。

供参考:nsIInterfaceRequestorXPCOMUtils

【讨论】:

  • 太棒了!我只是需要这个!谢谢!有没有办法阻止重定向? (可能我现在要开始调查,只是懒惰并在开始之前询问)还有可能从 ChromeWorker 做这样的事情吗?
  • @Noitidart:是的,你不必将 NS_OK 传递给回调,你也可以给 NS_BINDING_ABORTED 例如。 ChromeWorker 不工作,无法访问 XPCOM。
  • 谢谢! callback.onRedirectVerifyCallback(Components.results.NS_BINDING_ABORTED) 是否应该与我们 throw 时所做的不同,如 DXR 页面上所述 - dxr.mozilla.org/mozilla-central/source/netwerk/base/… ?问是因为我可能搞砸了哈哈
  • @Noitidart:不是真的,它应该做同样的事情。但是,大多数错误代码会显示在错误控制台中,但 NS_BIND‌​ING_ABORTED 不会。
  • 谢谢@Palant 我想为什么它为我记录是我没有在做throw Cr.NS_BINDING_ABORTED,但我在做throw new Error(Cr.NS_BINDING_ABORTED)。我现在试试。不管在我的测试中,当我用callback.onRedirectVerifyCallbackCr.NS_BINDING_ABORTED 进行测试时,它都会致命地结束它。所以事件不再触发,所以我的加载事件监听器不会发生。不像我扔。所以这就是回调会发生的事情 - "NS_BINDING_ABORTED: Component returned failure code: 0x804b0002 (NS_BINDING_ABORTED) [nsIAsyncVerifyRedirectCallback.onRedirectVerifyCallback"
【解决方案2】:

thx,代码有效,但与预期不符:A->B->C->D (channel_1 -> channel_2 -> channel_3 -> channel_4).

在我的情况下,它将记录A->B->C->D 的重定向链,例如:

A->B (channel_1 -> channel_2), than B->C (channel_1 -> channel_2), C->D (channel_1 -> channel_2); 其中channel_1 & channel_2 是随机哈希数。

所以我无法将链条链接在一起。这将是捕获事件链的策略(当页面重定向时使用元刷新、javascript、http...)?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多