我有一个这样的字符串:
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
}
当前回答
一个简单的答案是内置本地Node模块。(没有第三方npm模块)
querystring模块提供了解析和格式化URL查询字符串的实用程序。可以使用以下方法访问:
const querystring = require('querystring');
const body = "abc=foo&def=%5Basf%5D&xyz=5"
const parseJSON = querystring.parse(body);
console.log(parseJSON);
其他回答
在Mike Causer回答的基础上,我创建了这个函数,它考虑了具有相同键的多个参数(foo=bar&foo=baz)和逗号分隔的参数(foo=bar,baz,bin)。它还允许您搜索某个查询键。
function getQueryParams(queryKey) {
var queryString = window.location.search;
var query = {};
var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
var key = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1] || '');
// Se possui uma vírgula no valor, converter em um array
value = (value.indexOf(',') === -1 ? value : value.split(','));
// Se a key já existe, tratar ela como um array
if (query[key]) {
if (query[key].constructor === Array) {
// Array.concat() faz merge se o valor inserido for um array
query[key] = query[key].concat(value);
} else {
// Se não for um array, criar um array contendo o valor anterior e o novo valor
query[key] = [query[key], value];
}
} else {
query[key] = value;
}
}
if (typeof queryKey === 'undefined') {
return query;
} else {
return query[queryKey];
}
}
示例输入: foo.html吗?博兹,foo = bar&foo = baz&foo =鹿角的第二叉,buz&bar = 1, 2, 3
示例输出
{
foo: ["bar","baz","bez","boz","buz"],
bar: ["1","2","3"]
}
下面是硅制品方法的一个更简化的版本。
下面的函数可以从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; }
在&上拆分以获得名称/值对,然后在=上拆分每对。这里有一个例子:
var str = "abc=foo&def=%5Basf%5D&xy%5Bz=5"
var obj = str.split("&").reduce(function(prev, curr, i, arr) {
var p = curr.split("=");
prev[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
return prev;
}, {});
另一种方法,使用正则表达式:
var obj = {};
str.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
obj[decodeURIComponent(key)] = decodeURIComponent(value);
});
本文改编自约翰·瑞西格的《搜索和不替换》。
使用URLSearchParams JavaScript Web API非常简单,
var paramsString = "abc=foo&def=%5Basf%5D&xyz=5"; //returns an iterator object var searchParams = new URLSearchParams(paramsString); //Usage for (let p of searchParams) { console.log(p); } //Get the query strings console.log(searchParams.toString()); //You can also pass in objects var paramsObject = {abc:"forum",def:"%5Basf%5D",xyz:"5"} //returns an iterator object var searchParams = new URLSearchParams(paramsObject); //Usage for (let p of searchParams) { console.log(p); } //Get the query strings console.log(searchParams.toString());
# #的有用链接
URLSearchParams - Web api | MDN 简单的URL操作与URLSearchParams | Web |谷歌开发者
注意:IE不支持
许多其他的解决方案没有考虑到边界情况。
这个可以处理
空键a=1&b=2& 空值a=1&b 空值a=1&b= 未编码的等号a=1&b=2=3=4
decodeQueryString: qs => {
// expects qs to not have a ?
// return if empty qs
if (qs === '') return {};
return qs.split('&').reduce((acc, pair) => {
// skip no param at all a=1&b=2&
if (pair.length === 0) return acc;
const parts = pair.split('=');
// fix params without value
if (parts.length === 1) parts[1] = '';
// for value handle multiple unencoded = signs
const key = decodeURIComponent(parts[0]);
const value = decodeURIComponent(parts.slice(1).join('='));
acc[key] = value;
return acc;
}, {});
},