首页 > 解决方案 > JSON数据响应位置不正确

问题描述

我有一个从服务器调用 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 上显示正确的数据位置。请给我建议

标签: javascriptjsonnode.js

解决方案


两种选择:

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是“自己的”属性(不继承)并且它们没有整数索引名称(您的示例没有),然后:

确保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-inor Object.keys,它们没有被指定为遵循属性顺序。如果您需要按顺序排列一组属性名称,请使用Object.getOwnPropertyNames.

属性将按您想要的顺序排列,JSON.stringify指定为遵循该顺序,并JSON.parse指定在结果中按该顺序创建对象。因此,即使 JSON 不保证顺序,JavaScriptJSON.stringifyJSON.parse可以在非常有限的上下文中执行。

再次,虽然:推荐。

但在客户端我收到的结果有时像服务器端,有时像下面

服务器发送的内容更有可能发生变化(可能基于代码中的分支),而您只是按照您想要的顺序查看了一个。如果服务器发送您显示的 JSON,JSON.parse将保留该顺序(原因见上文)。


推荐阅读