我有一个这样的字符串:
abc=foo&def=%5Basf%5D&xyz=5
如何将其转换为这样的JavaScript对象?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
我有一个这样的字符串:
abc=foo&def=%5Basf%5D&xyz=5
如何将其转换为这样的JavaScript对象?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
当前回答
ES6有一个非常简单而不正确的答案:
console.log(
Object.fromEntries(new URLSearchParams(`abc=foo&def=%5Basf%5D&xyz=5`))
);
但是这一行代码不包括多个相同的键,你必须使用更复杂的东西:
function parseParams(params) {
const output = [];
const searchParams = new URLSearchParams(params);
// Set will return only unique keys()
new Set([...searchParams.keys()])
.forEach(key => {
output[key] = searchParams.getAll(key).length > 1 ?
searchParams.getAll(key) : // get multiple values
searchParams.get(key); // get single value
});
return output;
}
console.log(
parseParams('abc=foo&cars=Ford&cars=BMW&cars=Skoda&cars=Mercedes')
)
代码将生成如下结构:
[
abc: "foo"
cars: ["Ford", "BMW", "Skoda", "Mercedes"]
]
其他回答
有一个名为YouAreI.js的轻量级库,它经过测试,使这个非常简单。
YouAreI = require('YouAreI')
uri = new YouAreI('http://user:pass@www.example.com:3000/a/b/c?d=dad&e=1&f=12.3#fragment');
uri.query_get() => { d: 'dad', e: '1', f: '12.3' }
这是一个简单的版本,显然你需要添加一些错误检查:
var obj = {};
var pairs = queryString.split('&');
for(i in pairs){
var split = pairs[i].split('=');
obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
}
ES6一行(如果我们可以这样称呼它,看到长行)
[…新URLSearchParams (location.search) .entries())。Reduce ((prev, [key,val]) => {prev[key] = val;返回prev}, {})
另一种基于URLSearchParams最新标准的解决方案(https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
function getQueryParamsObject() {
const searchParams = new URLSearchParams(location.search.slice(1));
return searchParams
? _.fromPairs(Array.from(searchParams.entries()))
: {};
}
请注意,这个解决方案是利用
Array.from (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)
和lodash的_. fropairs (https://lodash.com/docs#fromPairs),以便简单。
因为您可以访问searchParams.entries()迭代器,所以创建一个更兼容的解决方案应该很容易。
下面是硅制品方法的一个更简化的版本。
下面的函数可以从USVString或Location解析查询字符串。
/** * Returns a plain object representation of a URLSearchParams object. * @param {USVString} search - A URL querystring * @return {Object} a key-value pair object from a URL querystring */ const parseSearch = (search) => [...new URLSearchParams(search).entries()] .reduce((acc, [key, val]) => ({ ...acc, // eslint-disable-next-line no-nested-ternary [key]: Object.prototype.hasOwnProperty.call(acc, key) ? Array.isArray(acc[key]) ? [...acc[key], val] : [acc[key], val] : val }), {}); /** * Returns a plain object representation of a URLSearchParams object. * @param {Location} location - Either a document or window location, or React useLocation() * @return {Object} a key-value pair object from a URL querystring */ const parseLocationSearch = (location) => parseSearch(location.search); console.log(parseSearch('?foo=bar&x=y&ids=%5B1%2C2%2C3%5D&ids=%5B4%2C5%2C6%5D')); .as-console-wrapper { top: 0; max-height: 100% !important; }
下面是上面代码的一行代码(125字节):
f是parsearchch
f=s=>[...new URLSearchParams(s).entries()].reduce((a,[k,v])=>({...a,[k]:a[k]?Array.isArray(a[k])?[...a[k],v]:[a[k],v]:v}),{})
Edit
下面是一个序列化和更新的方法:
const parseSearch = (search) => [...new URLSearchParams(search).entries()] .reduce((acc, [key, val]) => ({ ...acc, // eslint-disable-next-line no-nested-ternary [key]: Object.prototype.hasOwnProperty.call(acc, key) ? Array.isArray(acc[key]) ? [...acc[key], val] : [acc[key], val] : val }), {}); const toQueryString = (params) => `?${Object.entries(params) .flatMap(([key, values]) => Array.isArray(values) ? values.map(value => [key, value]) : [[key, values]]) .map(pair => pair.map(val => encodeURIComponent(val)).join('=')) .join('&')}`; const updateQueryString = (search, update) => (parsed => toQueryString(update instanceof Function ? update(parsed) : { ...parsed, ...update })) (parseSearch(search)); const queryString = '?foo=bar&x=y&ids=%5B1%2C2%2C3%5D&ids=%5B4%2C5%2C6%5D'; const parsedQuery = parseSearch(queryString); console.log(parsedQuery); console.log(toQueryString(parsedQuery) === queryString); const updatedQuerySimple = updateQueryString(queryString, { foo: 'baz', x: 'z', }); console.log(updatedQuerySimple); console.log(parseSearch(updatedQuerySimple)); const updatedQuery = updateQueryString(updatedQuerySimple, parsed => ({ ...parsed, ids: [ ...parsed.ids, JSON.stringify([7,8,9]) ] })); console.log(updatedQuery); console.log(parseSearch(updatedQuery)); .as-console-wrapper { top: 0; max-height: 100% !important; }