使用 Node.js 反序列化奇怪的查询字符串
Deserialize strange querystring with Node.js
我有以下字符串并想将其反序列化为一个对象:
responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00
&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8
&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM
&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application
(顺便说一句 - 这是使用经典 API 的 PayPal 自适应支付的响应)
https://developer.paypal.com/webapps/developer/docs/classic/api/adaptive-payments/Pay_API_Operation/
使用 Node.js 我可以使用
将其转换为项目数组
var qs = require('querystring');
var response = the-response-from-paypal;
var paypalResponse = qs.parse(response.toString());
console.log(paypalResponse["responseEnvelope.ack"])
//Renders: Failure
但我想将它转换成一个对象,可以像这样访问:
var ack = deserializedResponse.responseEnvelope.ack;
//etc
或JSON:
{
responseEnvelope: {
ack: "Failure",
timestamp: blah,
correlationId: "a58a06c1000d8",
...
},
error: [
{
errorId: 520003,
domain: "Platform",
...
}
]
}
是否有一些方便的工具可以做到这一点?
这是基于我对你的另一个 的回答。您只需要将递归函数包装在将为您构建整个对象的预处理中。
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return setObjVal(o, pair[0].split('.'), pair[1]);
}, {});
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
var arrayRegExp = /^(\w+)\((\d+)\)$/;
var input = 'responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application';
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return setObjVal(o, pair[0].split('.'), pair[1]);
}, {});
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
或者 如果您想像其他答案一样使用 lodash,您可以使用 _.set()
:
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return _.set(o, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
}, {});
var input = 'responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application';
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return _.set(o, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
}, {});
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
我有以下字符串并想将其反序列化为一个对象:
responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00
&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8
&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM
&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application
(顺便说一句 - 这是使用经典 API 的 PayPal 自适应支付的响应) https://developer.paypal.com/webapps/developer/docs/classic/api/adaptive-payments/Pay_API_Operation/
使用 Node.js 我可以使用
将其转换为项目数组var qs = require('querystring');
var response = the-response-from-paypal;
var paypalResponse = qs.parse(response.toString());
console.log(paypalResponse["responseEnvelope.ack"])
//Renders: Failure
但我想将它转换成一个对象,可以像这样访问:
var ack = deserializedResponse.responseEnvelope.ack;
//etc
或JSON:
{
responseEnvelope: {
ack: "Failure",
timestamp: blah,
correlationId: "a58a06c1000d8",
...
},
error: [
{
errorId: 520003,
domain: "Platform",
...
}
]
}
是否有一些方便的工具可以做到这一点?
这是基于我对你的另一个
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return setObjVal(o, pair[0].split('.'), pair[1]);
}, {});
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
var arrayRegExp = /^(\w+)\((\d+)\)$/;
var input = 'responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application';
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return setObjVal(o, pair[0].split('.'), pair[1]);
}, {});
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
或者 如果您想像其他答案一样使用 lodash,您可以使用 _.set()
:
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return _.set(o, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
}, {});
var input = 'responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application';
var newObj = input.split('&').reduce(function (o, str) {
var pair = str.split('=');
return _.set(o, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
}, {});
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>