【问题标题】:Using a JSON.parse reviver to obfuscate fields使用 JSON.parse reviver 混淆字段
【发布时间】:2012-05-22 15:34:36
【问题描述】:

我正在尝试使用 JSON.parse 滥用 reviver 函数。

我基本上是想让某些字段为“null”。

如果我这样做:

var json_data = JSON.parse(j, function(key, value) {
  if (key == "name") {        
    return value;
  } else {
    return null;    
  }    
});

整个 json_data 对象最终为空。事实上,不管我做什么else,它都定义了json_object的值。

有趣的是,这按预期工作:

var json_data = JSON.parse(j, function(key, value) {
  if (key == "name") {        
    return "name";
  } else {
    return value;    
  }    
});

属性“name”现在的值为“name”。

有问题的 JSON:

var j = '{"uuid":"62cfb2ec-9e43-11e1-abf2-70cd60fffe0e","count":1,"name":"Marvin","date":"2012-05-13T14:06:45+10:00"}';

更新

我刚刚意识到与我想做的相反的事情也可以,所以我可以取消 name 字段:

var json_data = JSON.parse(j, function(key, value) {
  if (key == "name") {        
    return null;
  } else {
    return value;    
  }    
});

【问题讨论】:

  • 另外,如果您 console.log -- 或 alert -- reviver 函数中的值,您会看到什么?我检查了API,到目前为止你的代码看起来不错......

标签: javascript json debugging reviver-function


【解决方案1】:

通过一些实验,看起来最终调用了函数,其中键是空字符串,值是顶级对象:

> JSON.parse('{"hello": "world"}', function(k, v) { console.log(arguments); return v; })
["hello", "world"]
["", Object]

所以你可以使用:

var json_data = JSON.parse(j, function(key, value) {
  if (key == "name" || key === "") {        
    return value;
  } else {
    return null;    
  }    
});

现在,由于 "" 似乎确实是一个有效的 JSON 密钥,因此要 100% 正确,最好使用类似以下内容:

var json_data;
JSON.parse(j, function(key, value) {
  if (key == "name") {        
    return value;
  } else if (key === "") {
    json_data = value;
    return null;
  } else {
    return null;    
  }    
});

但这可能有点偏执;)

【讨论】:

  • 该死……我喜欢那个编辑。它让我看起来好像引用了资料和资料;)
  • @David - 你的控制台示例真的很有帮助!我知道发生了什么,我想。返回的数组之一的键为“”,所以如果不检查,如果我理解正确,整个对象就会变为空?
  • 是的。就像@Corbin 所描述的那样,对 reviver 的最后一次调用将键设置为 "",并将值设置为顶级 JSON 对象(在我的示例中,{hello: "world"})。这个调用返回的值是JSON.parse返回的值,所以如果null从这里返回(就像在OP的代码中一样), JSON.parse`也将返回null。跨度>
【解决方案2】:

它有一个相当有趣的行为,即整个对象都包含在传递给 reviver 的对象中。

传递整个对象时,key为null。

http://jsfiddle.net/sGYGM/7/

var j = '{"uuid":"62cfb2ec-9e43-11e1-abf2-70cd60fffe0e","count":1,"name":"Marvin","date":"2012-05-13T14:06:45+10:00"}';

var json_data = JSON.parse(j, function(k, v) {
    if (k === "" || k == "name") {
        return v;
    } else {
        return null;
    }
});

console.log(json_data);

根据https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/parse

最终使用空字符串和最高值调用 reviver 以允许转换最高值。一定要正确处理这种情况,通常通过返回提供的值,否则 JSON.parse 将返回 undefined。

【讨论】:

  • 我不确定我是否理解为什么需要k === ""?这到底是做什么的?
  • @jmort253 作为对 reviver 函数的最后一次调用,传递了整个对象。换句话说, json_data 作为函数的最后一件事传递。在这种情况下,键是一个空字符串。
  • 现在,更好的问题:我想知道为什么他们选择使用空字符串(这是一个有效的 JSON 键)而不是像 undefined 这样的值,这不是一个有效的关键(并且有点道理)。
  • @DavidWolever 谁知道。这绝对没有多大意义。它可能与返回 undefined 使元素从对象中删除的行为有关。也许他们害怕如果他们将键设为 undefined 然后有人返回 undefined,他们怎么能从自身中删除整个对象呢? (尽管他们当然可以将对象设置为未定义。)
  • @corbin,我必须选择某人作为答案,而你们几乎同时发帖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2015-08-12
  • 2018-04-02
  • 1970-01-01
  • 2015-04-22
  • 2012-12-27
  • 1970-01-01
相关资源
最近更新 更多