【发布时间】:2016-03-05 08:16:07
【问题描述】:
我试图在启用按键排序的情况下获得与 pythons json.dumps() 相同的结果。这是作为 Postman 生成请求哈希的预请求脚本执行的。输出需要排序为有效的 json,用作散列的输入。我是 javascript 新手,看到许多旧答案声称无法对 javascript 中的对象进行排序。然而,必须有一个解决方案来生成给定标准的哈希。
- 无法更改对象结构。
- 只需要支持Chrome即可。
- 我可以使用库。
- requestParams 可以包含需要按任意深度排序的嵌套对象和数组。
这是我当前的代码。在 Chrome 控制台中,sortedResult 的对象预览是未排序的,但是当我展开对象和子对象时,Chrome 控制台将 sortedResult 显示为已排序,这正是它应该的方式。这给我的印象是 sortObject 正在工作。但是 requestOrdered 返回有效的 json 对象,但未排序。我最初的想法是 JSON.stringify() 可能正在对其进行排序。
const requestRebuilt = {"username": user, "password": password, "sTime": time, "function": function,
"functionParams": requestParams, "salt": salt};
function sortObject(object){
var keys = _.keys(object);
var sortedKeys = _.sortBy(keys, function(key){
//console.log(key);
return key;
});
var sortedObj = {};
var sortedObjJson = "";
for(var index in keys){
var key = keys[index];
//console.log(key + ' ' + typeof object[key]);
if(typeof object[key] == 'object' && !(object[key] instanceof Array)){
sortedObj[key] = sortObject(object[key]);
} else if(object[key] instanceof Array) {
//sortedObj[key] = object[key].sort();
var arrayLength = object[key].length;
for (var i = 0; i < arrayLength; i++) {
sortedObj[key] = sortObject(object[key][i]);
//console.log(object[key][i]);
}
} else {
sortedObj[key] = object[key];
}
}
return sortedObj;
}
const sortedResult = sortObject(requestRebuilt);
console.log(sortedResult);
const requestOrdered = JSON.stringify(sortedResult);
console.log(requestOrdered);
var hash = CryptoJS.SHA256(requestOrdered).toString();
postman.setGlobalVariable("hash", hash);
示例输入:
{
"username": "jdoe@mail.com",
"sTime": "2016-03-04T13:53:37Z",
"function": "begin",
"functionParams": {
"tip": "ABC123FFG",
"pad": 4 ,
"passenger": [{
"firstName": "John",
"phone": 1234567890,
"email": "jdoe@mail.com",
"dateOfBirth": "1915-10-02T00:00:00Z",
"bans": {
"weight": 9,
"count": 2
}
}
]},
"salt": "00d878f5e203",
"pep": "sdeODQ0T"
}
在 python 中,这是通过以下方式完成的:
ordered = json.dumps(
{"username": user, "password": password, "time": time, "function": function, "functionParams": functionParams, "salt": salt}
sort_keys=True, separators=(',', ':'))
下单结果:
{"function":"begin","functionParams":{"passenger":[{"bans":{"count":2,"weight":9},"dateOfBirth":"1915-10-02T00:00:00Z","email":"jdoe@mail.com","firstName":"John","phone":1234567890}],"pad":4,"tip":"ABC123FFG"},"pep":"sdeODQ0T","salt":"00d878f5e203","sTime":"2016-03-04T13:53:37Z","username":"jdoe@mail.com"}
印刷精美,便于阅读,但实际结果不应有空格或换行:
{
"function": "begin",
"functionParams": {
"passenger": [
{
"bans": {
"count": 2,
"weight": 9
},
"dateOfBirth": "1915-10-02T00:00:00Z",
"email": "jdoe@mail.com",
"firstName": "John",
"phone": 1234567890
}
],
"pad": 4,
"tip": "ABC123FFG"
},
"pep": "sdeODQ0T",
"salt": "00d878f5e203",
"sTime": "2016-03-04T13:53:37Z",
"username": "jdoe@mail.com"
}
【问题讨论】:
-
对象键在 JavaScript 中没有排序。因此,您不能使用
JSON.stringify来实现此目的。 -
有什么解决办法吗?如果 javascript 不能保持顺序,你怎么能正确地散列一个对象?
-
正如您所指出的,不可能在 JavaScript 中对对象键进行排序。你可以做的是创建一个
[ ['key1', 'value1'], ['key2', 'value2'] ]排序的数组来保留你感兴趣的顺序
标签: javascript python sorting recursion