JavaScript window.location does not set referer in the request header
Solution 1
Your post title shows that you want to change the current page programmatically using JavaScript but still having the HTTP referrer provided (from what I understood, using a <a>
tag is just for a test case).
You need to be aware of cross-browser issues:
- The HTTP referrer header (HTTP-Referer) is set when changing
window.location.href
under the following browsers:- MSIE 9 (but probably any version above 9)
- Firefox (at least 3.0, 3.5, 4.0, 5.0, but most probably all versions)
- Chrome (at least 9, but most probably all versions)
- Safari (at least 5, but most probably all versions)
- Opera (at least 11, but most probably all versions)
-
MSIE (at least 6, 7, 8): the referrer is not set when changing
window.location.href
(this is why some pseudo-solutions are based onmyLink.click()
) -
Firefox (at least 3.0, 3.5, 4.0): the
click
function does not exist (this is why pseudo-solutions based onmyLink.click()
do not work) -
Firefox 5 : the
click
function exists under Firefox 5 but does not change the window location, so all the methods relying on the existence of themyLink.click()
method will not work. CallingmyLink.onclick()
ormyLink.onClick()
raise an error ("onclick is not a function"), so solutions based on these calls will not work.
In order to manage these cross-browser issues, I'm using the following method:
function navigateToUrl(url) {
var f = document.createElement("FORM");
f.action = url;
var indexQM = url.indexOf("?");
if (indexQM>=0) {
// the URL has parameters => convert them to hidden form inputs
var params = url.substring(indexQM+1).split("&");
for (var i=0; i<params.length; i++) {
var keyValuePair = params[i].split("=");
var input = document.createElement("INPUT");
input.type="hidden";
input.name = keyValuePair[0];
input.value = keyValuePair[1];
f.appendChild(input);
}
}
document.body.appendChild(f);
f.submit();
}
navigateToUrl("http://foo.com/bar");
This solution works on all the browser flavors and version listed above. It has the advantage to be simple, multi-browser and easy to understand. Note that this has not been tested under HTTPS.
Solution 2
Setting window.location
is not the same as following a link on that page. It starts a new request for the page as thought the user typed the URL into the browser's address bar.
I did manage to locate a workaround:
function goTo(url)
{
var a = document.createElement("a");
if(!a.click) //for IE
{
window.location = url;
return;
}
a.setAttribute("href", url);
a.style.display = "none";
document.body.appendChild(a);
a.click();
}
It creates a link on the page and simulates a click. The result is a change in window.location
and the referrer is populated.
http://ianso.blogspot.com/2006/01/referer-header-not-set-on-http.html
Solution 3
I don't have enough points to comment on Evan's answer to suggest a correction so all I can do is post the correction here. In short, document.createElement(a)
is missing quotes and should be document.createElement("a")
instead. This should fix Kevin's concern about FF5 as well.
The whole function as I wrote it:
function goTo(url)
{
var a = document.createElement("a");
if (a.click)
{
// HTML5 browsers and IE support click() on <a>, early FF does not.
a.setAttribute("href", url);
a.style.display = "none";
document.body.appendChild(a);
a.click();
} else {
// Early FF can, however, use this usual method
// where IE cannot with secure links.
window.location = url;
}
}
This works in our HTTPS environment with IE7, IE8, FF3, FF7, and Chrome. So I imagine it works in FF5 as well. Without this workaround we get 403 errors in IE7 and IE8 when trying to set window.location. Regarding Sha Le's question as to why IE does this, I can only guess is that they believe it to be too insecure. I had a similar problem with window.open in IE that I had to work around as well.
Sha Le
Updated on July 09, 2022Comments
-
Sha Le almost 2 years
I understand relying on Referer in the request header is not right. But my question is, why IE does not set Referer to the Request Header if I use
window.location
? Any thoughts or fixes?This does not set Referer in the Request header:
function load1() { window.location = "https://" + serverURL + "/path/folder/page.aspx"; } <a href="javascript:load1()">Link 1</a>
While this sets:
<a href="https://hardcode.server.url/path/folder/page.aspx">Link 1</a>
-
Admin over 13 yearsYou don't need jQuery for this. $("body").appendChild(a) can be replaced with document.body.appendChild(a);
-
Admin over 13 yearsThank you very much for doing so. I thought you were a heartless robot. :)
-
Evan Mulawski over 13 yearsAll this does is set the href of an anchor tag. It doesn't do anything unless the user clicks that link.
-
Sunil486 almost 13 yearsSeeing evidence that Firefox 5 returns true for a.click but does not navigate to the href when a.click() is executed.
-
Sunil486 almost 13 years"will not cause an A element to initiate navigation as if a real mouse-click had been received" : developer.mozilla.org/en/DOM/element.click
-
six8 almost 12 yearsThis works great unless you want to use method="GET" and have url parameters in your url.
-
Julien Kronegg almost 12 years@Cixate : true for URL parameters (I edited the code), but I don't understand the argument for the form method since the default form method is GET.
-
six8 almost 12 yearsSorry, wasn't implying you needed the
method=GET
in the tag, was just saying that you couldn't use parameters in the URL if the form was using the GET method. But your hidden parameters fix works nicely. -
Zorayr about 11 yearsOn Safari 5.0 running on Windows 7, this causes the following error:
TypeError: 'undefined' is not a function (evaluating 'a.click()')
. -
Evan Mulawski about 11 years@Zorayr: That was because I was passing
a
tocreateElement
instead of"a"
. I have corrected the code. -
Zorayr about 11 yearsI am still having the same issue with
createElement('a')
. Any ideas? -
TryHarder over 10 yearsThis is probably obvious, (to all people except me) but if you run this script before page load you are going to get TypeError: document.body is null appendChild. So run it after the page has loaded :)
-
undoIT about 10 yearsLovely! Another code-bloat hack to support Internet Explorer turd monkey. The only real solution for this is to wipe Internet Explorer off the face of the World Wide Web. The hack mentioned here does work in my case, however, Internet Explorer 8 displays a security warning, which the visitor must accept and then after the page is reloaded, the redirect to download a file works properly.