2012-06-26 4 views
3

브라우저에서 요청한 URL의 리디렉션 수를 찾고, 가능한 경우 자바 스크립트를 통해 해당 URL의 리디렉션 된 경로를 추적하려고합니다.자바 스크립트에서 URL의 리디렉션 경로 추적

예를 들어, 내 브라우저에서 'A'를 요청하면 리디렉션 흐름을 A-> B-> C-> D로 지정하십시오. 의미는 'D'로 리디렉션됩니다. 이 경우 3 개의 301 리디렉션 상태 코드와 하나의 200 상태 코드가 필요합니다.

나는 addon.js에서 아래의 방법을 시도했다 (그리고 Firefox 브라우저에 addon을 만들었다).

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로 생각됩니다).

자바 스크립트를 통해 URL의 모든 301 리디렉션을 가져올 수 있습니까?

감사합니다,

+0

흥미로운 질문입니다. 내 직감은 각 리디렉션이 새로운 요청을 구성하므로 새로운 응답을 구성하므로 리디렉션 체인의 각 링크에서 쿠키 또는 세션 변수를 만들거나 업데이트해야한다고 말합니다. – jackwanders

+0

여기에 몇 가지 정보입니다 : https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIWebProgressListener https://developer.mozilla.org/en/Creating_Sandboxed_HTTP_Connections#HTTP_notifications https://developer.mozilla.org/en/ XPCOM_Interface_Reference/nsIChannelEventSink – Yansky

+0

리디렉션 된 체인의 각 링크를 잡는 방법을 간략하게 설명 할 수 있습니다. "리디렉션 된 웹 사이트"(리디렉션 체인의 마지막 하나)를 내 브라우저에서 가져 오는 중입니다. 200 개의 상태가 있습니다. 감사합니다, – Mmh

답변

1

nsIXMLHttpRequest interface 유형 nsIChannel의 (단지 확장 액세스) 회원 channel 있습니다. 자신의 콜백을 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.

+0

최고! 나는 단지 이것을 필요로했다! 고맙습니다! 리디렉션을 차단할 수있는 방법이 있습니까? (아마도 나는 지금부터 시작해서 게으르다가 시작하기 전에 묻기 시작할 것입니다) 또한 ChromeWorker에서 이와 같은 작업을 수행 할 수 있습니까? – Noitidart

+1

@Noitidart : 예, NS_OK를 콜백에 전달할 필요가 없습니다. 예를 들어 NS_BINDING_ABORTED도 제공 할 수 있습니다. ChromeWorker는 작동하지 않으며 XPCOM에 액세스 할 수 없습니다. –

+0

감사! 'callback.onRedirectVerifyCallback (Components.results.NS_BINDING_ABORTED)'이 DXR 페이지에 명시된 것처럼'throw '할 때와 다른지 - https://dxr.mozilla.org/mozilla-central/source/netwerk/base /nsIChannelEventSink.idl#94?내가 뭔가를 망쳐 놓았을지도 모른다고 묻기. – Noitidart

-1

들으 코드는 작동하지만 예상하지 : A->B->C->D (channel_1 -> channel_2 -> channel_3 -> channel_4).

내 경우는 같은 A->B->C->D의 리디렉션 체인을 기록합니다 : channel_1 & channel_2 임의의 해시 번호입니다

A->B (channel_1 -> channel_2), than B->C (channel_1 -> channel_2), C->D (channel_1 -> channel_2);.

그래서 체인을 연결할 수 없습니다. 그것은 이벤트의 사슬을 포착하는 전략이 될 것입니다 (페이지 리다이렉션, 메타 새로 고침, 자바 스크립트, http ...)?

관련 문제