Looking for a way to parse key pairs out of the hash/fragment of a URL into an object/associative array with JavaScript/JQuery
- You could probably do it with a pretty simple regexp. What "format" are the key/value pairs in the URL?gnarf– gnarf2010-11-16 18:59:44 +00:00Commented Nov 16, 2010 at 18:59
- Same as they would be in a query string- see my answerYarin– Yarin2010-11-16 19:23:33 +00:00Commented Nov 16, 2010 at 19:23
10 Answers
Use URLSearchParams. It's fully supported in major browsers and server-side JavaScript runtimes that implement WHATWG URL Standard. Browser coverage: https://caniuse.com/urlsearchparams.
Read a key from the current URL (assuming you are running on a browser UA):
// window.location.hash = "#any_hash_key=any_value" const parsedHash = new URLSearchParams( window.location.hash.substring(1) // any_hash_key=any_value ); console.log(parsedHash.get("any_hash_key")); // any_value Read a key from an arbitrary URL (make sure to check for exceptions that may be thrown by URL constructor when given URL is not valid):
const url = new URL("https://example.com#foo=bar&baz=qux&val=val+has+spaces"); const parsedHash = new URLSearchParams( url.hash.substring(1) // foo=bar&baz=qux&val=val+has+spaces ); console.log(parsedHash.get("baz")); // qux console.log(parsedHash.get("val")); // val has spaces Check out the Mozilla docs I linked above to see all of the methods of the interface.
10 Comments
Object.fromEntries(parsedHash)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
5 Comments
r regexp?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!)
3 Comments
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'}
5 Comments
#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.URLSearchParams which is the issue i was trying to fix by downvoting.URLSearchParams described in stackoverflow.com/a/57018898/481422 as using browser native implementations for certain functionalities at least in theory should be faster than any logic you create with javascript.I am using jQuery URL Parser library.
1 Comment
I was looking through a bunch of answers for this problem and wound up cobbling them together using one line with reduce:
const hashObj = location.hash.replace('#', '').split('&').reduce((prev, item) => Object.assign({[item.split('=')[0]]: item.split('=')[1]}, prev), {}); There's obviously a lot going on in that one line. It can be rewritten like this for clariry:
const hashObj = location.hash.replace('#', '').split('&').reduce((prev, item) => { return Object.assign({[item.split('=')[0]]: item.split('=')[1]}, prev); }, {}); Comments
My answer to this question should do what you're looking for:
url_args_decode = function (url) { var args_enc, el, i, nameval, ret; ret = {}; // use the DOM to parse the URL via an 'a' element el = document.createElement("a"); el.href = url; // strip off initial ? on search and split args_enc = el.search.substring(1).split('&'); for (i = 0; i < args_enc.length; i++) { // convert + into space, split on =, and then decode args_enc[i].replace(/\+/g, ' '); nameval = args_enc[i].split('=', 2); ret[decodeURIComponent(nameval[0])]=decodeURIComponent(nameval[1]); } return ret; }; Comments
You can also use the .hash property, demonstrated in this scrolling table of contents example for a clicked link or for the locatioin.
Comments
This jquery API does parse hash tags: https://jhash.codeplex.com/
// get the "name" querystring value var n = jHash.val('name'); // get the "location" querystring value var l = jHash.val('location'); // set some querystring values jHash.val({ name: 'Chris', location: 'WI' }); 1 Comment
You might want to check out jsuri. It seems to work well for me.