How to deterministically verify that a JSON object hasn't been modified?

前端 未结 8 1769
忘了有多久
忘了有多久 2020-11-30 04:38

According to MDN documentation for JSON.stringify:

Properties of non-array objects are not guaranteed to be stringified in any particular order. Do

8条回答
  •  北荒
    北荒 (楼主)
    2020-11-30 05:01

    JavaScript keys are intrinsically unordered. You have to write your own Stringifier to make this work, so I did.

    Usage:

    JSONc14n.stringify(obj)
    

    Source:

    var JSONc14n = {
        stringify: function(obj){
            var json_string,
                keys,
                key,
                i;
    
            switch(this.get_type(obj)){
                case "[object Array]":
                    json_string = "[";
                    for(i = 0; i < obj.length; i++){
                        json_string += this.stringify(obj[i]);
                        if(i < obj.length - 1) json_string += ",";
                    }
                    json_string += "]";
                    break;
                case "[object Object]":
                    json_string = "{";
                    keys = Object.keys(obj);
                    keys.sort();
                    for(i = 0; i < keys.length; i++){
                        json_string += '"' + keys[i] + '":' + this.stringify(obj[keys[i]]);
                        if(i < keys.length - 1) json_string += ",";
                    }
                    json_string += "}";
                    break;
                case "[object Number]":
                    json_string = obj.toString();
                    break;
                default:
                    json_string = '"' + obj.toString().replace(/["\\]/g,
                        function(_this){
                            return function(character){
                                return _this.escape_character.apply(_this, [character]);
                            };
                        }(this)
                    ) + '"';
            }
            return json_string;
        },
        get_type: function(thing){
            if(thing===null) return "[object Null]";
            return Object.prototype.toString.call(thing);
        },
        escape_character: function(character){
            return this.escape_characters[character];
        },
        escape_characters: {
            '"': '\\"',
            '\\': '\\\\'
        }
    };
    

提交回复
热议问题