node.js - 使用 Node.js 反序列化奇怪的查询字符串

标签 node.js paypal deserialization query-string paypal-adaptive-payments

我有以下字符串并想将其反序列化为一个对象:

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",
            ...
        }
    ]

}

是否有一些方便的工具可以做到这一点?

最佳答案

这基于我对您的其他 SO question 的回答.您只需要将递归函数包装在将为您构建整个对象的预处理中。

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>

关于node.js - 使用 Node.js 反序列化奇怪的查询字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31256936/

相关文章:

javascript - 使用NodeJS + HTML建立MySQL数据库似乎不起作用

node.js - Node 错误 : Route. get() 需要回调函数,但得到了 [对象未定义]

node.js - 如何列出本地npm包内容

node.js - Saisjs find() 回调操作

Paypal IPN https 更改 2016

html - 如何将 Paypal 下拉菜单更改为单选按钮?

php - 调用 RedirectUrls,忽略 onAuthorize 函数

c# - 扩展字典的属性不会在序列化中显示

c# - 在 .NET 中使用部分 JSON 更新反序列化对象

java - 在 Java 中反序列化复合对象