Parsing URL hash/fragment identifier with JavaScript

69,303

Solution 1

Check out: jQuery BBQ

jQuery BBQ is designed for parsing things from the url (query string or fragment), and goes a bit farther to simplify fragment-based history. This is the jQuery plugin Yarin was looking for before he put together a pure js solution. Specifically, the deparam.fragment() function does the job. Have a look!

(The support site I'm working on uses an asynchronous search, and because BBQ makes it trivial to tuck entire objects into the fragment I use it to 'persist' my search parameters. This gives my users history states for their searches, and also allows them to bookmark useful searches. Best of all, when QA finds a search defect they can link straight to the problematic results!)

Solution 2

Here it is, modified from this query string parser:

function getHashParams() {

    var hashParams = {};
    var e,
        a = /\+/g,  // Regex for replacing addition symbol with a space
        r = /([^&;=]+)=?([^&;]*)/g,
        d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
        q = window.location.hash.substring(1);

    while (e = r.exec(q))
       hashParams[d(e[1])] = d(e[2]);

    return hashParams;
}

No JQuery/plug-in required

Update:

I'm now recommending the jQuery BBQ plugin as per Hovis's answer. It covers all hash parsing issues.

Update (2019)

Apparently there is now a URLSearchParams function - see answer from @Berkant

Solution 3

Use URLSearchParams. Browser coverage: https://caniuse.com/urlsearchparams. It's fully supported in major browsers. Here is a polyfill if you need to use this on unsupported browsers.

To read a simple key:

// window.location.hash = "#any_hash_key=any_value"

const parsedHash = new URLSearchParams(
  window.location.hash.substring(1) // skip the first char (#)
);

console.log(parsedHash.get("any_hash_key")); // any_value

Check out the Mozilla docs I linked above to see all of the methods of the interface.

Solution 4

Do this in pure Javascript:

var hash = window.location.hash.substr(1);

var result = hash.split('&').reduce(function (result, item) {
    var parts = item.split('=');
    result[parts[0]] = parts[1];
    return result;
}, {});

http://example.com/#from=2012-01-05&to=2013-01-01

becomes

{from: '2012-01-05', to:'2013-01-01'}

Solution 5

I am using jQuery URL Parser library.

Share:
69,303

Related videos on Youtube

Yarin
Author by

Yarin

Products PDF Buddy - Popular online PDF editor Gems Snappconfig - Smarter Rails app configuration

Updated on April 18, 2022

Comments

  • Yarin
    Yarin about 2 years

    Looking for a way to parse key pairs out of the hash/fragment of a URL into an object/associative array with JavaScript/JQuery

    • gnarf
      gnarf over 13 years
      You could probably do it with a pretty simple regexp. What "format" are the key/value pairs in the URL?
    • Yarin
      Yarin over 13 years
      Same as they would be in a query string- see my answer
  • Dan Esparza
    Dan Esparza over 13 years
    This parses the url itself -- not the hash items. Useful, but not what the original question is about.
  • Yarin
    Yarin over 12 years
    @Hovis- this is indeed an awesome plugin, and in fact I've switched over to using it as well. Giving you the answer as it's a much better option than my scratch function.
  • The Muffin Man
    The Muffin Man over 12 years
    I'm going to start using this.
  • Christophe
    Christophe over 11 years
    could you elaborate on the "hash parsing issues"? I have the same need and I don't see anything wrong with your answer.
  • Yarin
    Yarin over 10 years
    @Christophe- I honestly can't recall. I'm sure my code works fine, but BBQ is a total plugin with hashchange events, query string parsing, etc, so probably that's what I meant..
  • nostromo
    nostromo over 10 years
    BBQ doesn't work well with Jquery 1.9+ and throws exceptions on load. It hasn't been updated in over three years. I'm not sure BBQ is still a good recommendation. You may be able to hack it to get it to work, see this: github.com/cowboy/jquery-bbq/pull/41
  • SomethingOn
    SomethingOn about 10 years
    For basic handling your script is awesome!! Too often we default to jQuery libraries for basic tasks. Thanks!
  • SomeoneElse
    SomeoneElse almost 9 years
    use gatoatigrado 's answer, it's better then the one I posted
  • Gone Coding
    Gone Coding over 8 years
    The link is now dead.
  • Gebb
    Gebb over 6 years
    What does a semicolon do in the r regexp?
  • crthompson
    crthompson over 5 years
    Jquery BBQ is no longer being updated and has issues with the latest JQuery.
  • Richard
    Richard over 4 years
    Agreed. Also, for multiple params, the format is as you would expect: a=foo&b=bar
  • Charming Robot
    Charming Robot almost 4 years
    This should be the top answer, instead of all the ancient ones. Thanks!
  • John Henckel
    John Henckel over 3 years
    This does not handle decoding, for example #this=is+a+test the plus signs should be convert to spaces... and there are a dozen other special cases. It is crazy to try to implement this yourself. It is such a common problem.
  • John Henckel
    John Henckel over 3 years
    i retract the 'crazy to try...' comment! trying to implement something is a great way to learn. Despite being 3 yrs old, this is still a common question, and downvoting is how we curate the knowledge. At the moment your answer is rated higher than the one about URLSearchParams which is the issue i was trying to fix by downvoting.
  • worldsayshi
    worldsayshi over 2 years
    Also, for anyone that wants the parsed hash as an object instead: Object.fromEntries(parsedHash)
  • crthompson
    crthompson about 2 years
    @JohnHenckel, if you need url decoding, just add a line to do url decoding. The reason why this has been such a popular answer is that it doesnt use other libraries. Also, its had several years to get to this level. Given time, the others will to. No need to be petty, upvote what you like, let others do the same. ;)
  • Chakib Salah
    Chakib Salah about 2 years
    I think substr can be replaced with slice , since substr became deprecated