如何将URL参数转换为JavaScript对象?在2021年...请认为这已过时。编辑原始答案
2022-08-29 23:32:42
我有一个这样的字符串:
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
}
此编辑根据注释改进并解释了答案。
var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
例
解析分五步:abc=foo&def=%5Basf%5D&xyz=5
abc=foo","def=[asf]","xyz=5
abc":"foo","def":"[asf]","xyz":"5
{"abc":"foo","def":"[asf]","xyz":"5"}
这是合法的 JSON。
改进的解决方案允许在搜索字符串中包含更多字符。它使用齐磊函数进行URI解码:
var search = location.search.substring(1);
JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })
例
search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar";
给
Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"}
单行本:
JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')
从ES6开始,Javascript提供了几个结构,以便为此问题创建一个高性能的解决方案。
这包括使用URLSearchParams和迭代器
let params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
params.get("abc"); // "foo"
如果您的用例要求您实际将其转换为对象,则可以实现以下函数:
function paramsToObject(entries) {
const result = {}
for(const [key, value] of entries) { // each 'entry' is a [key, value] tupple
result[key] = value;
}
return result;
}
const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const entries = urlParams.entries(); //returns an iterator of decoded [key,value] tuples
const params = paramsToObject(entries); //{abc:"foo",def:"[asf]",xyz:"5"}
我们可以使用 Object.fromEntries,替换为 .paramsToObject
Object.fromEntries(entries)
要迭代的值对是列表名称-值对,其中键是名称,值是值。
由于 返回一个可迭代对象,因此使用 spread 运算符而不是调用也会根据其规范生成条目:URLParams
.entries
const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const params = Object.fromEntries(urlParams); // {abc: "foo", def: "[asf]", xyz: "5"}
注意:所有值都是根据 URLSearchParams 规范自动字符串
正如@siipe所指出的,包含多个相同键值的字符串将被强制转换为最后一个可用值:实质上将变为:。foo=first_value&foo=second_value
{foo: "second_value"}
根据这个答案:https://stackoverflow.com/a/1746566/1194694 没有规范来决定如何处理它,每个框架的行为可能不同。
一个常见的用例是将两个相同的值联接到一个数组中,使输出对象变成:
{foo: ["first_value", "second_value"]}
这可以通过以下代码实现:
const groupParamsByKey = (params) => [...params.entries()].reduce((acc, tuple) => {
// getting the key and value from each tuple
const [key, val] = tuple;
if(acc.hasOwnProperty(key)) {
// if the current key is already an array, we'll add the value to it
if(Array.isArray(acc[key])) {
acc[key] = [...acc[key], val]
} else {
// if it's not an array, but contains a value, we'll convert it into an array
// and add the current value to it
acc[key] = [acc[key], val];
}
} else {
// plain assignment if no special case is present
acc[key] = val;
}
return acc;
}, {});
const params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5&def=dude');
const output = groupParamsByKey(params) // {abc: "foo", def: ["[asf]", "dude"], xyz: 5}