Getting URL hash location, and using it in jQuery

254,071

Solution 1

Editor's note: the approach below has serious security implications and, depending upon the version of jQuery you are using, may expose your users to XSS attacks. For more detail, see the discussion of the possible attack in the comments on this answer or this explanation on Security Stack Exchange.

You can use the location.hash property to grab the hash of the current page:

var hash = window.location.hash;
$('ul'+hash+':first').show();

Note that this property already contains the # symbol at the beginning.

Actually you don't need the :first pseudo-selector since you are using the ID selector, is assumed that IDs are unique within the DOM.

In case you want to get the hash from an URL string, you can use the String.substring method:

var url = "http://example.com/file.htm#foo";
var hash = url.substring(url.indexOf('#')); // '#foo'

Advice: Be aware that the user can change the hash as he wants, injecting anything to your selector, you should check the hash before using it.

Solution 2

location.hash is not safe for IE , in case of IE ( including IE9 ) , if your page contains iframe , then after manual refresh inside iframe content get location.hash value is old( value for first page load ). while manual retrieved value is different than location.hash so always retrieve it through document.URL

var hash = document.URL.substr(document.URL.indexOf('#')+1) 

Solution 3

For those who are looking for pure javascript solution

 document.getElementById(location.hash.substring(1)).style.display = 'block'

Hope this saves you some time.

Solution 4

Since jQuery 1.9, the :target selector will match the URL hash. So you could do:

$(":target").show(); // or $("ul:target").show();

Which would select the element with the ID matching the hash and show it.

Solution 5

I would suggest better cek first if the current page has a hash. Otherwise it will be undefined.

$(window).on('load', function(){        
    if( location.hash && location.hash.length ) {
       var hash = decodeURIComponent(location.hash.substr(1));
       $('ul'+hash+':first').show();;
    }       
});
Share:
254,071
Robbie White
Author by

Robbie White

Updated on February 18, 2020

Comments

  • Robbie White
    Robbie White over 4 years

    I'd like to get the value after a hash in the URL of the current page and then be able to apply this in a new function... eg.

    The URL could be

    www.example.com/index.html#foo
    

    And I would like to use this in conjunction with the following piece of code

    $('ul#foo:first').show();
    

    I'm kinda assuming/hoping there is some way of grabbing this, and turning it into a variable that I can then use in the second piece of code.

  • Tgr
    Tgr about 12 years
    Note that jQuery selectors can be used to execute custom javascript code, so using unsanitized hashes is horribly, horribly insecure. There is a half-assed fix for this in recent jQuery versions for selectors which contain a # before the injected code, but you are still at risk if you remove the # mark from the beginning of location.hash. E. g. var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content')); this will execute a script tag put in the hash. It is a good habit to use $('body').find('ul'+hash+':first') instead of $('ul'+hash+':first').
  • Tim
    Tim about 12 years
    Some browers return the hash symbol, and some don't, so it's safer to use: var hash = location.hash.replace('#', '');
  • snapfractalpop
    snapfractalpop almost 12 years
    @Tgr When you say that "using unsanitized hashes is horribly, horribly insecure," can you explain what can be done? Are we talking about a user hacking his or her own computer? I just can't think of what the real vulnerability is and would really appreciate some elaboration.
  • Tgr
    Tgr almost 12 years
    @snapfractalpop: as I said, script tags in the hash get executed under the right conditions. The hash can be set by the attacker to an arbitrary value by e.g. tricking the user to visit a web page controlled by the attacker and redirecting him from there.
  • snapfractalpop
    snapfractalpop almost 12 years
    @Tgr: let me know if I have the scenario right: Alice runs a web site, Bob is a visitor. Charlie comes along and is able to [somehow?] change the hash so that Bob gets redirected to a different link? I just want to fully understand the risk..how can Charlie affect Bob's session?
  • Tgr
    Tgr almost 12 years
    Alice runs a web site, Bob visits it, authenticates and receives a session cookie. (Some time might pass here, Bob might even close his browser.) Charlie sends Bob a mail saying "check out this cool link!". Bob opens the link, which leads to a site controlled by Charlie. The page redirects Bob's browser to a page on Alice's site with an attack payload in the hash. The payload is executed, and since the browser still remembers the cookies, it can just send them to Charlie.
  • Tgr
    Tgr almost 12 years
    There can be other scenarios, but along the same lines. E.g. Bob is browsing Alice's site through HTTPS, from an insecure wifi connection. He is also browsing some other sites through plain HTTP. Charlie performs a man-in-the-middle attack against the HTTP connection, and injects a script which redirects to an HTTPS URL on Alice's site; the hash part of the URL is crafted to send Bob's login details to Charlie.
  • snapfractalpop
    snapfractalpop almost 12 years
    @Tgr, thank you for elaborating and connecting the dots. This concrete example makes me (and hopefully others) more inclined towards vigilance in keeping things secure.
  • Deepak Patil
    Deepak Patil almost 11 years
    location.hash value gives old value in case of refreshing page containing iframe. So prefer to retrieve it through document.URL.indexOf('#')+1
  • Deepak Patil
    Deepak Patil almost 11 years
    Update: document.URL does not contain hash value on firefox 3.6 so location.href is safe var hash = location.href.substr(location.href.indexOf('#')+1)
  • user
    user almost 10 years
    @Tgr You say good habit to use $('body').find(..) vs $(..) - Is that a good practice generally when you have user input?
  • Tgr
    Tgr almost 10 years
    @buffer: $(userInput) is generally unsafe because $ is overloaded and might either search for existing nodes or create new ones depending on whether the string contains <> characters. $(document).find(userInput) will always search for existing nodes so it is less unsafe. That said, the best practice is to always sanitize user input, e.g. if you use alphanumeric ids make sure it is alphanumeric.
  • ina
    ina over 4 years
    is there a way to extract the hash as a string instead of match id?
  • j08691
    j08691 over 4 years
    @ina Do you mean get the hash from jQuery's :target as a string? If so I don't believe so.