我有一个这样的字符串:
abc=foo&def=%5Basf%5D&xyz=5
我怎样才能将它转换成这样的 JavaScript 对象?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
原文由 Alex 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个这样的字符串:
abc=foo&def=%5Basf%5D&xyz=5
我怎样才能将它转换成这样的 JavaScript 对象?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
原文由 Alex 发布,翻译遵循 CC BY-SA 4.0 许可协议
从 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)
。
要迭代的值对是列表名称-值对,键是名称,值是值。
由于 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}
原文由 silicakes 发布,翻译遵循 CC BY-SA 4.0 许可协议
10 回答11.2k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
在 2021 年…请认为这个已经过时了。
编辑
此编辑根据评论改进并解释了答案。
例子
解析
abc=foo&def=%5Basf%5D&xyz=5
分五步:decodeURI: abc=foo&def=[asf]&xyz=5
转义引号:相同,因为没有引号
替换 &:
abc=foo","def=[asf]","xyz=5
替换 =:
abc":"foo","def":"[asf]","xyz":"5
用花括号和引号括起来:
{"abc":"foo","def":"[asf]","xyz":"5"}
这是合法的 JSON。
改进的解决方案 允许搜索字符串中包含更多字符。它使用 reviver 函数进行 URI 解码:
例子
给
原始答案
单线: