I want to set a page's base href attribute in Javascript based off of the current hostname. I have generated HTML pages that can be viewed on different hostnames, which means generating a base href tag will work in one hostname but will be incorrect in the other.
The correct way of doing this is to do a document.write of the tag based off the current hostname:
Correct:
<script type="text/javascript">
document.write("<base href='http://" + document.location.host + "' />");
</script>
This method has produced correct results in IE, FF, Chrome, and Safari. It produces a (correct) different result than doing the following:
Incorrect:
<script type="text/javascript">
var newBase = document.createElement("base");
newBase.setAttribute("href", document.location.hostname);
document.getElementsByTagName("head")[0].appendChild(newBase);
</script>
I think you'd better do it this way
<script type="text/javascript">
document.head.innerHTML = document.head.innerHTML + "<base href='" + document.location.href + "' />";
</script>
As location.hostname does not return the application context root! You could also log the document.location on the console console.log to see all available metadata on document.location.
I have to disagree with the top answer. It does not account for the protocol so it will fail.
A working solution that I have to account for protocol / host / port is the following
var base = document.createElement('base');
base.href = window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
document.getElementsByTagName('head')[0].appendChild(base);
This currently works fine in all major browsers including IE11
I have used this to make an npm package that also supports adding a suffix to the end of this base href if anyone is interested
https://www.npmjs.com/package/dynamic-base
https://github.com/codymikol/dynamic-base
document.write("");
<script>
document.write("<base href='"+ window.location.protocol +'//' + window.location.host + "' >");
</script>
Related
What I want is do this:
var siteBaseUrl = window.location.origin;
But in IE 9 it's returning undefined
Trying to understand how do I use modernizr from the suggestion here:
$window.location.origin gives wrong value when using IE
I updated my code to add this block before my siteurl:
if (!window.location.origin) {
window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
}
var siteBaseUrl = window.location.origin;
So now the above works, but I am not sure if modernizr suggestion in the link above can help me do it differently.
Or may be I am confusing myself and the above code is working due to modernizr.
All modernizr will do in this case is tell you that the method is missing. Since it does not fix/polyfill anything itself, you would have to do the same work.
There would be no difference.
I am using
history.pushState('id','myTitle','myURL');
to manipulate the displayed URL and the history stack.
At some point I am pushing get parameters like so:
history.pushState('id','myTitle','?mySubLinkedStuff=hotSubLinkedStuff');
Now when I do
history.pushState('id','myTitle','#justSomeHashtag');
it produces http://example.com?mySubLinkedStuff=hotSubLinkedStuff#justSomeHashtag
I can also overwrite the value of mySubLinkedStuff but not seem to be able to get rif of it alltogether.
Desired result:
http://example.com#justSomeHashtag or http://example.com/#justSomeHashtag
and obviously I don't want to make the whole roundtrip over the server and I also want to avoid using absolute path or URL to keep the project portable.
As NimrodArgov rightly remarked: overwriting existing get-parameter strings works if you
push the full URL.
So for ensuring portability of the app (keep it usable on various domains) I did this:
history.statePush(document.location.origin + window.location.pathname + '#myHashValue');
Works perfectly well and fast.
To push current address without GET parameters :
history.pushState("id", "myTitle",
location.protocol + "//" + location.host +
location.pathname + location.hash
);
Other than that ;
To push a hash change I could do :
history.pushState("id", "myTitle",
location.protocol + "//" + location.host +
location.pathname + location.search + "#myHashHere"
);
To push a query change I could do :
history.pushState("id", "myTitle",
location.protocol + "//" + location.host +
location.pathname + "?my=query&over=here" + location.hash
);
※ Sorry I don’t have enough karma to just comment on Max’s answer… :/
I am trying to understand what risk Fortify is seeing here. I am new to XSS work and I want to be sure before I decide this isn't a real issue. I can't see how a person could use this code for anything but messing up their own computer, so I am curious if I am missing something.
Here is the source text
Fortify says that the line where window.location.href is being assigned is the vulnerability. "Unvalidated" data sent to browser.
<c:if test="${isExternalUser}">
<script type="text/javascript">
$(function(){
$('#logoutLink').on('click', function(){
var logoutUrl = window.appSettings.context + '/external/logout/';
$.get(logoutUrl).done(function(){
window.location.href = window.location.protocol + "//" + window.location.host + window.appSettings.context + "/?${ssw:encodeJS(header['policy-signout'])}";
});
});
});
</script>
</c:if>
As far as I can tell there is no risk here.
I can't see any risk.
The only unvalidated data external to the browser is
${ssw:encodeJS(header['policy-signout'])}
which is correctly being JS encoded. Maybe Fortify isn't picking up on this fact.
You could try splitting that line (as a test) just to make sure it is the encodejs that is not being recognised as executing JS encoding.
var policySignout = "${ssw:encodeJS(header['policy-signout'])}";
window.location.href = window.location.protocol + "//" + window.location.host + window.appSettings.context + "/?" + policySignout;
I'm making an ebay template for myself, and I want to use a name anchor to jump to different section on the page template. But Ebay adds something to the URL therefore breaking the name anchor.
Since this seems to be Firefox related only, someone suggested that I need to strip "&bv=mozilla" from the URL then it would work. If there are any javascript experts out here that can help me out, I would highly appreciate it.
var documentUrl = location.href;
var newUrl = documentUrl.replace("&bv=mozilla","");
Try this:
var url = location.protocol + '//' + location.host + location.pathname;
or this:
var url = location.protocol + '//' + location.host + ':' + location.port + location.pathname;
if it is on the same page.
Otherwise, you could try this:
var url = 'insert URL here';
var new_url = url.substring(0, url.indexOf('?'));
See substring, indexOf and window.location.
I'm looking for a neat way of getting the URL of the current document in Javascript.
The URL should be clean of parameters (?parameter1=bla¶meter2=bla)
The URL should be clean of hash tags (#jumppoint)
http/https should be removed/consolidated into http
I know i can get the current URL with location.href and then use some regular expressions to clean it up but maybe there is a nicer/cleaner solution for getting rid of the junk?
There are many other parameters than the href in window.location. See full reference here: https://developer.mozilla.org/en/DOM/window.location
What you are looking for as a starter might be the window.location.hostname:
"the host name (without the port number or square
brackets)."
From the example URL http://[www.example.com]:80/search?q=devmo#test the hostname will be www.example.com.
If you also want to include the path and force a http:// protocol, try:
'http://' + window.location.hostname + window.location.pathname;
As a side note, a nifty trick to get the same parameters from another URL than the window.location is to create an empty anchor:
var a = document.createElement('a');
a.href = 'http://www.example.com:80/search?q=devmo#test';
console.log('http://' + a.hostname + a.pathname);
None of the given answers address the fact that the protocol can be http or https as in the OPs title. To accommodate this I suggest:
document.location.protocol +"//"+ document.location.hostname + document.location.pathname
The Location object got what you need
window.location.hostname + window.location.pathname
You have document.location object, so:
var oLoc = document.location,
sUrl = oLoc.protocol + oLoc.hostname;
// or "http://" + oLoc.hostname
You can use these replacement functions to remove the hash and search arguments and normalize https to http:
url = url.replace(/#[^#]*$/, "").replace(/\?[^\?]*$/, "").replace(/^https:/, "http:");
Or, if all you really want is the domain and path, you can just use this:
window.location.hostname + window.location.pathname
Please try this snippet:
if (!window.location.origin){
// For IE
window.location.origin = window.location.protocol + "//" + (window.location.port ? ':' + window.location.port : '');
}
url = window.location.origin + window.location.pathname;
document.write('Origin url: ' + url);
This page indicates that you could probably use window.location.host to get the part you're actually interested in. I haven't tested it, though.
Try:
window.location.hostname;