-
-
Save pirate/9298155edda679510723 to your computer and use it in GitHub Desktop.
function getUrlParams(search) { | |
const hashes = search.slice(search.indexOf('?') + 1).split('&') | |
const params = {} | |
hashes.map(hash => { | |
const [key, val] = hash.split('=') | |
params[key] = decodeURIComponent(val) | |
}) | |
return params | |
} | |
console.log(getUrlParams(window.location.search)) |
Improving the @tbillington answer, when only have the key, the key loses the last letter and the value, instead of empty, is assigned with the key.
Eg ?debug&name=John&last-name
will be returned: {debu: "debug", name: "John", last-nam: "last-name"}
instead of: {debug: null, name: "John", last-name: null}
The code:
const decodeURLParams = search => {
const hashes = search.slice(search.indexOf("?") + 1).split("&");
return hashes.reduce((params, hash) => {
const split = hash.indexOf("=");
if (split < 0) {
return Object.assign(params, {
[hash]: null
});
}
const key = hash.slice(0, split);
const val = hash.slice(split + 1);
return Object.assign(params, { [key]: decodeURIComponent(val) });
}, {});
};
What about hash ? http://foo.com/#?a=1 What about hash ? http://foo.com/#/?a=1 What about hash ? http://foo.com/?b=2#?a=1
@cancerbergoSgx
How about cheating and treating as a search string?
// URL hash http://foo.com/?c=2#?a=1&b=works
new URLSearchParams(document.location.hash.replace('#','?')).get('b')
// returns 'works'
// Chrome Version 78.0.3904.87 (Official Build) (64-bit)
You would still need to parse document.location.search
and merge the two objects if you wanted a unified search plus hash parameters data structure.
What about hash ? http://foo.com/#?a=1 What about hash ? http://foo.com/#/?a=1 What about hash ? http://foo.com/?b=2#?a=1
How to handle the value with equal(=) sign? like:
keyA=value1&keyB=hff92hfgg=&keyC=value3
That's not a valid value @zerocoolElite, it needs to be URL-encoded (=
becomes %3D
when URL-encoded).
That's not a valid value @zerocoolElite, it needs to be URL-encoded (
=
becomes%3D
when URL-encoded).
Then the search string should be encoded first before passing to getUrlParams()?
I've tested all the functions above by https://runkit.com/embed/n18yhf9u2nqc and the conclusion is that url-parse and URLSearchParams is the rightest and most expected ones against the standard url - Node.js built-in module. Even the query-string module is not work as expected.
const search = '?abc=foo&def=[asf]&xyz==5&flag&&double&q=test1=test2&keyB=hff92hfgg=';
console.log((search));
const url = require('url')
console.log('0. url - the Node.js built-in module √');
console.log(url.parse(search, true).query);
console.log('1. queryString ×');
console.log(queryString.parse(search));
const parse = require('url-parse')
console.log('2. url-parse √');
console.log(parse(search, true).query);
console.log('3. URLSearchParams √');
console.log([...new URLSearchParams(search).entries()].reduce((q, [k, v]) => Object.assign(q, {[k]: v}), {}))
result:
?abc=foo&def=[asf]&xyz==5&flag&&double&q=test1=test2&keyB=hff92hfgg=
0. url - the Node.js built-in module √
Object {abc: "foo", def: "[asf]", double: "", flag: "", keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}
1. queryString ×
Object {: null, abc: "foo", def: "[asf]", double: null, flag: null, keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}
2. url-parse √
Object {abc: "foo", def: "[asf]", double: "", flag: "", keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}
3. URLSearchParams √
Object {abc: "foo", def: "[asf]", double: "", flag: "", keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}
So this fails if you have select multiple
- or any other input with multiple values that's named with square brackets:
<select name="statuses[]" multiple>...
Here's a slight adjustment, hopefully I'm not stepping on any edge cases:
function getUrlParams(search) {
const hashes = search.slice(search.indexOf('?') + 1).split('&')
const params = {}
hashes.map(hash => {
let [key, val] = hash.split('=')
key = decodeURIComponent(key)
if (key.indexOf('[') > -1) { // handle multiple type inputs
if (typeof params[key] === 'undefined') {
params[key] = []
}
params[key].push(decodeURIComponent(val))
} else {
params[key] = decodeURIComponent(val)
}
})
return params
}
Unfortunately even the native URLSearchParams
implementation doesn't handle array query parameters. :(
So, here's another take on array query parameters. Tested on
https://gist.github.com/pirate/9298155edda679510723?abc=foo&def=[asf]&xyz==5&flag&&double&q=test1=test2&keyB=hff92hfgg=&arr[]=ArrayValue1&arr[]=ArrayValue2&arr[]=ArrayValue3&arr2[0]=ArrayValue1&arr2[1]=ArrayValue2&arr2[2]=ArrayValue3&fields=kind,items(title,characteristics/length)
const getQueryParams = () => {
let params = {};
(new URLSearchParams(document.location.search)).forEach((d, e) => {
let a = decodeURIComponent(e), c = decodeURIComponent(d)
if (a.endsWith("[]")) {
a = a.replace("[]", ""), params[a] || (params[a] = []), params[a].push(c)
} else {
let b = a.match(/\[([a-z0-9_\/\s,.-])+\]$/g)
b ? (a = a.replace(b, ""), b = b[0].replace("[", "").replace("]", ""), params[a] || (params[a] = []), params[a][b] = c) : params[a] = c
}
})
return params
}
I create an alternative project if you want to use es6 module, with a very simple api:
query
Note: the above functions all trim any characters including & following the first equal sign in a query value.
Eg
?q=test=abc
will be returned astest
by the above functions.Obligatory own version of the above ;)