Reputation: 417
I am trying to find number of redirections of a requested url in a browser, and if possible want to track the redirected path of that URL through javascript.
For example, if i request 'A' in my browser.assume the redirection flow as A->B->C->D. Means,it gets redirected to 'D'. In this case i need to get three 301 redirect status codes and one 200 ok status code.
I tried the below method in my addon.js(and made an addon to firefox browser).
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
var StatusValue = req.status;
It is giving 200 ok (I think it is of final url).
Is it possible to get all 301 redirects of a URL through Javascript.
Thanks,
Upvotes: 4
Views: 3457
Reputation: 1
thx, the code works, but not as expected: A->B->C->D (channel_1 -> channel_2 -> channel_3 -> channel_4).
In my case it will record a redirect chain of A->B->C->D
like:
A->B (channel_1 -> channel_2), than B->C (channel_1 -> channel_2), C->D (channel_1 -> channel_2);
where channel_1 & channel_2
are random hash numbers.
So I can not link the chain together. that would be the strategy to capture the chain of events (while the pages redirect using, meta-refresh, javascript, http...)?
Upvotes: -1
Reputation: 57681
nsIXMLHttpRequest
interface has a member channel
(accessible to extensions only) of type nsIChannel
. You can assign your own callbacks to its notificationCallbacks
property and implement nsIChannelEventSync
interface to receive redirection events. Something along these lines:
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);
This code makes sure to always call the old notification callbacks while logging any calls to nsIChannelEventSync.asyncOnChannelRedirect
.
For reference: nsIInterfaceRequestor, XPCOMUtils.
Upvotes: 1