我有一个这样的字符串:
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
}
当前回答
下面是我的快速而粗糙的版本,基本上它将以'&'分隔的URL参数拆分为数组元素,然后迭代该数组,将以'='分隔的键/值对添加到一个对象中。我使用decodeURIComponent()将编码字符转换为正常的字符串等效(因此%20变成空格,%26变成'&'等):
function deparam(paramStr) {
let paramArr = paramStr.split('&');
let paramObj = {};
paramArr.forEach(e=>{
let param = e.split('=');
paramObj[param[0]] = decodeURIComponent(param[1]);
});
return paramObj;
}
例子:
deparam('abc=foo&def=%5Basf%5D&xyz=5')
返回
{
abc: "foo"
def:"[asf]"
xyz :"5"
}
唯一的问题是xyz是一个字符串而不是一个数字(由于使用decodeURIComponent()),但除此之外,它不是一个坏的起点。
其他回答
如果您需要递归,您可以使用小巧的js-extension-ling库。
npm i js-extension-ling
const jsx = require("js-extension-ling");
console.log(jsx.queryStringToObject("a=1"));
console.log(jsx.queryStringToObject("a=1&a=3"));
console.log(jsx.queryStringToObject("a[]=1"));
console.log(jsx.queryStringToObject("a[]=1&a[]=pomme"));
console.log(jsx.queryStringToObject("a[0]=one&a[1]=five"));
console.log(jsx.queryStringToObject("http://blabla?foo=bar&number=1234"));
console.log(jsx.queryStringToObject("a[fruits][red][]=strawberry"));
console.log(jsx.queryStringToObject("a[fruits][red][]=strawberry&a[1]=five&a[fruits][red][]=cherry&a[fruits][yellow][]=lemon&a[fruits][yellow][688]=banana"));
这将输出如下内容:
{ a: '1' }
{ a: '3' }
{ a: { '0': '1' } }
{ a: { '0': '1', '1': 'pomme' } }
{ a: { '0': 'one', '1': 'five' } }
{ foo: 'bar', number: '1234' }
{
a: { fruits: { red: { '0': 'strawberry' } } }
}
{
a: {
'1': 'five',
fruits: {
red: { '0': 'strawberry', '1': 'cherry' },
yellow: { '0': 'lemon', '688': 'banana' }
}
}
}
注意:它基于loctus parse_str函数(https://locutus.io/php/strings/parse_str/)。
我还需要在URL的查询部分处理+ (decodeURIComponent没有),所以我改编了Wolfgang的代码成为:
var search = location.search.substring(1);
search = search?JSON.parse('{"' + search.replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
function(key, value) { return key===""?value:decodeURIComponent(value)}):{};
在我的例子中,我使用jQuery来获得URL准备好的表单参数,然后这个技巧来构建一个对象,然后我可以轻松地更新对象上的参数并重新构建查询URL,例如:
var objForm = JSON.parse('{"' + $myForm.serialize().replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
function(key, value) { return key===""?value:decodeURIComponent(value)});
objForm.anyParam += stringToAddToTheParam;
var serializedForm = $.param(objForm);
下面是我的快速而粗糙的版本,基本上它将以'&'分隔的URL参数拆分为数组元素,然后迭代该数组,将以'='分隔的键/值对添加到一个对象中。我使用decodeURIComponent()将编码字符转换为正常的字符串等效(因此%20变成空格,%26变成'&'等):
function deparam(paramStr) {
let paramArr = paramStr.split('&');
let paramObj = {};
paramArr.forEach(e=>{
let param = e.split('=');
paramObj[param[0]] = decodeURIComponent(param[1]);
});
return paramObj;
}
例子:
deparam('abc=foo&def=%5Basf%5D&xyz=5')
返回
{
abc: "foo"
def:"[asf]"
xyz :"5"
}
唯一的问题是xyz是一个字符串而不是一个数字(由于使用decodeURIComponent()),但除此之外,它不是一个坏的起点。
在2021年…请认为这是过时的。
Edit
这个编辑改进并解释了基于评论的答案。
var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
例子
分五个步骤解析abc=foo&def=%5Basf%5D&xyz=5:
decodeURI: abc = foo&def = xyz (asf) = 5 转义引号:相同,因为没有引号 替换&:abc=foo","def=[asf]","xyz=5 " 5 . Replace =: abc":"foo","def":"[asf]","xyz": Suround卷曲和引用:{“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,"\":\"")) + '"}')
下面是我用的一个例子:
var params = {};
window.location.search.substring(1).split('&').forEach(function(pair) {
pair = pair.split('=');
if (pair[1] !== undefined) {
var key = decodeURIComponent(pair[0]),
val = decodeURIComponent(pair[1]),
val = val ? val.replace(/\++/g,' ').trim() : '';
if (key.length === 0) {
return;
}
if (params[key] === undefined) {
params[key] = val;
}
else {
if ("function" !== typeof params[key].push) {
params[key] = [params[key]];
}
params[key].push(val);
}
}
});
console.log(params);
基本用法。 ? = aa&b = bb 对象{a: "aa", b: "bb"}
重复参数,例如。 ? = aa&b = bb&c = cc&c =土豆 对象{a: "aa", b: "bb", c: ["cc","potato"]}
钥匙不见了。 ? = aa&b = bb = cc 对象{a: "aa", b: "bb"}
缺少值,例如。 = aa&b = bb&c ? 对象{a: "aa", b: "bb"}
上述JSON/regex解决方案在这个古怪的url上抛出了一个语法错误: ? = aa&b = bb&c = & = dd&e 对象{a: "aa", b: "bb", c: ""}