JSON数据响应位置不正确

时间:2018-08-28 08:34:09

标签: javascript json node.js

我有一个从服务器这样调用API的功能:

 getDataSet(callback) {
            request.open('POST', `${apiPath}`);
            request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            request.onreadystatechange = function () {
                if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
                    return callback(null, JSON.parse(request.responseText));
                }
            };
            request.send();
        }

 dataSetDetail.getDataSet((err, response) => {
        if (err) return (console.log(err));
        if (response.success) {
            let data = response.data.dataSetDetails.slice(0, 10);
        }
    });

这是服务器端:

router.post('/:projectid/data/:id', isAuthenticated, (req, res, next) => {
    let dataSetId = parseInt(req.params.id);
    dataSet.getDataSet(dataSetId)
        .then(dataSet => {
            if (!lodash.isNull(dataSet)) {
                res.setHeader('Content-Type', 'application/json');
                return res.json({
                    data: dataSet,
                    success: true,
                });

            } else {
                logger.error('Cannot find data set with id: ' + dataSetId);
                res.redirect('../data');
            }
        })
        .catch(e => {
            logger.error(e);
            res.redirect('../data');
        })

});

服务器的响应是:

[
  {
    "left": "2",
    "right": "3",
    "operator": "+"
  },
  {
    "left": "6",
     "right": "4"
    "operator": "-"
  }
]

但是在客户端,我有时收到类似于服务器端的结果,有时如下所示:

[
      {
        "operator": "+",
        "right": "3",
        "left": "2",

      },
      {
        "operator": "-",
        "right": "4",
        "left": "6"
      }
    ]

因为我需要在UI上显示正确的数据位置。请给我建议

2 个答案:

答案 0 :(得分:5)

为您提供两个选择:

1。使用数组

JSON对象表示法没有顺序。来自http://json.org

  

对象是一组无序的名称/值对。

(我的重点。)

尽管JavaScript对象现在具有顺序(自ES2015起),但通常不是最佳实践。

如果您需要订单,特别是如果需要通过JSON保留订单,请使用数组:

[
    ["2", "3", "+"],
    ["6", "4", "-"]
]

如果需要属性名称,也发送它们:

{
    names: ["left", "right", "operator"],
    data:  [
        ["2", "3", "+"],
        ["6", "4", "-"]
    ]
}

强烈推荐此方法,而不是方法2。

2。确保以正确的顺序创建dataSet

如果您对使用对象和依赖属性顺序一无所知(建议),并且两端都使用了JavaScript(看起来好像是这样),并且您在dataSet上的属性是“自有”属性(未继承),并且它们没有integer index names(您的示例属性没有),然后:

确保按照要序列化属性的顺序在dataSet中创建对象,例如:

const dataSet = [];
dataSet.push({
    left: "2",
    right: "3",
    operator: "+"
});

const dataSet = [];
let entry = {};
entry.left = "2";
entry.right = "3";
entry.operator = "+";
dataSet.push(entry);
// ...

const dataSet = [];
let entry = {};
entry.operator = "+";  // *** These are
entry.right = "3";     // *** in the
entry.left = "2";      // *** wrong order
dataSet.push(entry);
// ...

请勿使用for-inObject.keys,未指定它们遵循属性顺序。如果需要按顺序排列属性名称数组,请使用Object.getOwnPropertyNames

这些属性将按照您想要的顺序排列,JSON.stringify被指定为遵循该顺序,并且JSON.parse被指定为以其顺序在结果中创建对象。因此,即使JSON不能保证顺序,JavaScript的JSON.stringifyJSON.parse都只能在非常有限的上下文中使用。

再次,但:推荐。

  

但是在客户端,我有时会收到类似于服务器端的结果,有时会如下所示

服务器发送的内容更有可能发生变化(可能基于代码中的分支),并且发生这种情况的原因是,您只是查看了想要的顺序。如果服务器发送了您显示的JSON,则JSON.parse将保留该顺序(有关原因,请参见上文)。

答案 1 :(得分:1)

实际上,如果您使用(。)点运算符调用值,则JSON属性的顺序将无关紧要。但是您可以使用stringify函数自定义排列。请参阅代码

var output=[
      {
        "operator": "+",
        "right": "3",
        "left": "2",

      },
      {
        "operator": "-",
        "right": "4",
        "left": "6"
      }
    ];

var custom = JSON.parse(JSON.stringify( output, ["left","right","operator"] , 4));
console.log(custom);