ติดตามเส้นทางการเปลี่ยนเส้นทางของ URL ในจาวาสคริปต์

ฉันกำลังพยายามค้นหาจำนวนการเปลี่ยนเส้นทางของ URL ที่ร้องขอในเบราว์เซอร์ และหากเป็นไปได้ต้องการติดตามเส้นทางการเปลี่ยนเส้นทางของ URL นั้นผ่านจาวาสคริปต์

ตัวอย่างเช่น หากฉันร้องขอ 'A' ในเบราว์เซอร์ของฉัน ให้ถือว่าโฟลว์การเปลี่ยนเส้นทางเป็น A->B->C->D หมายความว่ามันถูกเปลี่ยนเส้นทางไปที่ 'D' ในกรณีนี้ ฉันต้องได้รับรหัสสถานะการเปลี่ยนเส้นทาง 301 สามรหัส และรหัสสถานะ 200 ok หนึ่งรหัส

ฉันลองวิธีด้านล่างใน addon.js ของฉัน (และสร้าง addon ให้กับเบราว์เซอร์ Firefox)

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

มันให้ 200 โอเค (ฉันคิดว่ามันเป็น URL สุดท้าย)

เป็นไปได้ไหมที่จะได้รับการเปลี่ยนเส้นทาง URL ทั้งหมด 301 รายการผ่าน Javascript

ขอบคุณ,


person Mmh    schedule 26.06.2012    source แหล่งที่มา
comment
คำถามที่น่าสนใจ สัญชาตญาณของฉันคือการบอกว่าคุณจะต้องสร้าง/อัปเดตคุกกี้หรือตัวแปรเซสชันในแต่ละลิงก์ในห่วงโซ่การเปลี่ยนเส้นทาง เนื่องจากการเปลี่ยนเส้นทางแต่ละครั้งถือเป็นคำขอใหม่ และดังนั้นจึงเป็นการตอบกลับใหม่   -  person jackwanders    schedule 26.06.2012
comment
นี่คือข้อมูลบางส่วน: developer.mozilla.org/en/XPCOM_Interface_Reference/ developer.mozilla.org/en/ developer.mozilla.org/en/XPCOM_Interface_Reference/   -  person Yansky    schedule 27.06.2012
comment
คุณช่วยอธิบายสั้น ๆ ได้ไหมว่าจะจับแต่ละลิงค์ในลูกโซ่ที่ถูกเปลี่ยนเส้นทางได้อย่างไร เพราะฉันได้รับเนื้อหาเว็บไซต์ที่ถูกเปลี่ยนเส้นทาง (อันสุดท้ายในห่วงโซ่การเปลี่ยนเส้นทาง) ในเบราว์เซอร์ของฉัน และสถานะตกลง 200 รายการสำหรับสิ่งนั้น ขอบคุณ,   -  person Mmh    schedule 27.06.2012


คำตอบ (2)


nsIXMLHttpRequest อินเทอร์เฟซ มีสมาชิก 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

สำหรับการอ้างอิง: nsIInterfaceRequestor, XPCOMUtils

person Wladimir Palant    schedule 28.06.2012
comment
สุดยอด! ฉันต้องการสิ่งนี้! ขอบคุณ! มีวิธีใดที่จะบล็อกการเปลี่ยนเส้นทางหรือไม่? (บางทีฉันกำลังจะเริ่มสืบสวนตอนนี้ แค่ขี้เกียจและถามก่อนที่จะเริ่ม) และเป็นไปได้ไหมที่จะทำสิ่งนี้จาก ChromeWorker - person Noitidart; 18.09.2016
comment
@Noitidart: ใช่ คุณไม่จำเป็นต้องส่ง NS_OK ไปยังการโทรกลับ คุณสามารถให้ NS_BINDING_ABORTED ได้เช่นกัน ChromeWorker ไม่ทำงาน แต่ไม่สามารถเข้าถึง XPCOM - person Wladimir Palant; 18.09.2016
comment
ขอบคุณ! ควรทำ callback.onRedirectVerifyCallback(Components.results.NS_BINDING_ABORTED) แตกต่างจากสิ่งที่เราทำเมื่อเรา throw ตามที่ระบุไว้ในหน้า DXR - dxr.mozilla.org/mozilla-central/source/netwerk/base/ ? ที่ถามเพราะว่าอาจจะทำอะไรเสียหาย 555 - person Noitidart; 18.09.2016
comment
@Noitidart: ไม่จริง มันควรจะทำสิ่งเดียวกัน อย่างไรก็ตาม รหัสข้อผิดพลาดส่วนใหญ่จะแสดงใน Error Console แต่ NS_BIND‌​ING_ABORTED จะไม่แสดง - person Wladimir Palant; 18.09.2016
comment
ขอบคุณ @Palant ฉันคิดว่าทำไมมันถึงบันทึกสำหรับฉันคือฉันไม่ได้ทำ throw Cr.NS_BINDING_ABORTED แต่ฉันกำลังทำ throw new Error(Cr.NS_BINDING_ABORTED) ฉันจะลองตอนนี้ ไม่ว่าอะไรในการทดสอบของฉันเมื่อฉันทำ callback.onRedirectVerifyCallback กับ Cr.NS_BINDING_ABORTED มันจะจบลงอย่างสาหัส ดังนั้นเหตุการณ์จึงไม่เริ่มทำงานอีกต่อไป ดังนั้นตัวฟังเหตุการณ์โหลดของฉันจึงไม่เกิดขึ้น ไม่เหมือนถ้าฉันโยน นี่คือสิ่งที่เกิดขึ้นกับการโทรกลับ - "NS_BINDING_ABORTED: Component returned failure code: 0x804b0002 (NS_BINDING_ABORTED) [nsIAsyncVerifyRedirectCallback.onRedirectVerifyCallback" - person Noitidart; 18.09.2016
comment
มันแปลกมากที่ throw Cr.NS_BINDING_ABORTED ใส่ลงในคอนโซล uncaught exception: 2152398850 (unknown) ในขณะที่ทำ throw new Error(Cr.NS_BINDING_ABORTED จะใส่ลงในคอนโซล Error: 2152398850 bootrap.js:1990:5 เอ๊ะ มันอาจเป็นการตั้งค่านักพัฒนาของฉัน ฉันจะเลิกยุ่งแล้ว ฮ่าๆ - person Noitidart; 18.09.2016

ขอบคุณ รหัสใช้งานได้ แต่ไม่เป็นไปตามที่คาดไว้: 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 คือหมายเลขแฮชแบบสุ่ม

ฉันก็เลยไม่สามารถล่ามโซ่เข้าด้วยกันได้ นั่นจะเป็นกลยุทธ์ในการจับห่วงโซ่ของเหตุการณ์ (ในขณะที่หน้าเปลี่ยนเส้นทางโดยใช้, meta-refresh, javascript, http...)

person Martin    schedule 19.01.2018