我如何以易于阅读(供人类阅读)的格式显示JSON?我主要寻找缩进和空白,甚至是颜色/字体样式等。


当前回答

出于调试目的,我使用:

console.debug("%o", data);

https://getfirebug.com/wiki/index.php/Console_APIhttps://developer.mozilla.org/en-US/docs/DOM/console

其他回答

对Ruby的其他漂亮打印机不满意,我自己编写了(NeatJSON),然后将其移植到JavaScript,包括一个免费的在线格式化程序。该代码在MIT许可证下是免费的(相当宽松)。

功能(全部可选):

设置线宽并换行,使对象和数组在合适时保持在同一行上,否则每行换行一个值。如果愿意,对对象关键点排序。对齐对象关键点(对齐冒号)。将浮点数格式化为特定的小数位数,而不打乱整数。“短”换行模式将左括号和右括号/大括号与值放在同一行,提供一些人更喜欢的格式。对数组和对象的间距、括号之间、冒号和逗号之前/之后进行精细控制。函数可用于web浏览器和Node.js。

我将在这里复制源代码,这样这不仅仅是一个库的链接,但我鼓励您转到GitHub项目页面,因为它将保持最新,而下面的代码不会。

(function(exports){
exports.neatJSON = neatJSON;

function neatJSON(value,opts){
  opts = opts || {}
  if (!('wrap'          in opts)) opts.wrap = 80;
  if (opts.wrap==true) opts.wrap = -1;
  if (!('indent'        in opts)) opts.indent = '  ';
  if (!('arrayPadding'  in opts)) opts.arrayPadding  = ('padding' in opts) ? opts.padding : 0;
  if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
  if (!('afterComma'    in opts)) opts.afterComma    = ('aroundComma' in opts) ? opts.aroundComma : 0;
  if (!('beforeComma'   in opts)) opts.beforeComma   = ('aroundComma' in opts) ? opts.aroundComma : 0;
  if (!('afterColon'    in opts)) opts.afterColon    = ('aroundColon' in opts) ? opts.aroundColon : 0;
  if (!('beforeColon'   in opts)) opts.beforeColon   = ('aroundColon' in opts) ? opts.aroundColon : 0;

  var apad  = repeat(' ',opts.arrayPadding),
      opad  = repeat(' ',opts.objectPadding),
      comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
      colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);

  return build(value,'');

  function build(o,indent){
    if (o===null || o===undefined) return indent+'null';
    else{
      switch(o.constructor){
        case Number:
          var isFloat = (o === +o && o !== (o|0));
          return indent + ((isFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+''));

        case Array:
          var pieces  = o.map(function(v){ return build(v,'') });
          var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
          if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
          if (opts.short){
            var indent2 = indent+' '+apad;
            pieces = o.map(function(v){ return build(v,indent2) });
            pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
            pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
            return pieces.join(',\n');
          }else{
            var indent2 = indent+opts.indent;
            return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';
          }

        case Object:
          var keyvals=[],i=0;
          for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];
          if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
          keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);
          var oneLine = indent+"{"+opad+keyvals+opad+"}";
          if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
          if (opts.short){
            var keyvals=[],i=0;
            for (var k in o) keyvals[i++] = [indent+' '+opad+JSON.stringify(k),o[k]];
            if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
            keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
            if (opts.aligned){
              var longest = 0;
              for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
              var padding = repeat(' ',longest);
              for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
            }
            for (var i=keyvals.length;i--;){
              var k=keyvals[i][0], v=keyvals[i][1];
              var indent2 = repeat(' ',(k+colon).length);
              var oneLine = k+colon+build(v,'');
              keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
            }
            return keyvals.join(',\n') + opad + '}';
          }else{
            var keyvals=[],i=0;
            for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];
            if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
            if (opts.aligned){
              var longest = 0;
              for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
              var padding = repeat(' ',longest);
              for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
            }
            var indent2 = indent+opts.indent;
            for (var i=keyvals.length;i--;){
              var k=keyvals[i][0], v=keyvals[i][1];
              var oneLine = k+colon+build(v,'');
              keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
            }
            return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'
          }

        default:
          return indent+JSON.stringify(o);
      }
    }
  }

  function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
    var result = '';
    while(true){
      if (times & 1) result += str;
      times >>= 1;
      if (times) str += str;
      else break;
    }
    return result;
  }
  function padRight(pad, str){
    return (str + pad).substring(0, pad.length);
  }
}
neatJSON.version = "0.5";

})(typeof exports === 'undefined' ? this : exports);

我使用JSONView Chrome扩展插件(它非常漂亮:):

编辑:添加了jsonreport.js

我还发布了一个在线独立的JSON漂亮打印查看器jsonreport.js,它提供了一个可读的HTML5报告,可以用来查看任何JSON数据。

您可以在新的JavaScript HTML5报告格式中阅读更多关于该格式的信息。

找不到任何能为控制台提供良好语法高亮显示的解决方案,所以这里是我的2p

安装并添加cli高亮显示依赖项

npm install cli-highlight --save

全局定义logjson

const highlight = require('cli-highlight').highlight
console.logjson = (obj) => console.log(
                               highlight( JSON.stringify(obj, null, 4), 
                                          { language: 'json', ignoreIllegals: true } ));

Use

console.logjson({foo: "bar", someArray: ["string1", "string2"]});

我想在这里展示我的jsonAnalyze方法,它只打印了JSON结构,但在某些情况下,打印整个JSON会更有用。

假设您有这样一个复杂的JSON:

let theJson = {
'username': 'elen',
'email': 'elen@test.com',
'state': 'married',
'profiles': [
    {'name': 'elenLove', 'job': 'actor' },
    {'name': 'elenDoe', 'job': 'spy'}
],
'hobbies': ['run', 'movies'],
'status': {
    'home': { 
        'ownsHome': true,
        'addresses': [
            {'town': 'Mexico', 'address': '123 mexicoStr'},
            {'town': 'Atlanta', 'address': '4B atlanta 45-48'},
        ]
    },
    'car': {
        'ownsCar': true,
        'cars': [
            {'brand': 'Nissan', 'plate': 'TOKY-114', 'prevOwnersIDs': ['4532354531', '3454655344', '5566753422']},
            {'brand': 'Benz', 'plate': 'ELEN-1225', 'prevOwnersIDs': ['4531124531', '97864655344', '887666753422']}
        ]
    }
},
'active': true,
'employed': false,
};

然后该方法将返回如下结构:

username
email
state
profiles[]
    profiles[].name
    profiles[].job
hobbies[]
status{}
    status{}.home{}
        status{}.home{}.ownsHome
        status{}.home{}.addresses[]
            status{}.home{}.addresses[].town
            status{}.home{}.addresses[].address
    status{}.car{}
        status{}.car{}.ownsCar
        status{}.car{}.cars[]
            status{}.car{}.cars[].brand
            status{}.car{}.cars[].plate
            status{}.car{}.cars[].prevOwnersIDs[]
active
employed

这是jsonAnalysis()代码:

function jsonAnalyze(obj) {
        let arr = [];
        analyzeJson(obj, null, arr);
        return logBeautifiedDotNotation(arr);

    function analyzeJson(obj, parentStr, outArr) {
        let opt;
        if (!outArr) {
            return "no output array given"
        }
        for (let prop in obj) {
            opt = parentStr ? parentStr + '.' + prop : prop;
            if (Array.isArray(obj[prop]) && obj[prop] !== null) {
                    let arr = obj[prop];
                if ((Array.isArray(arr[0]) || typeof arr[0] == "object") && arr[0] != null) {                        
                    outArr.push(opt + '[]');
                    analyzeJson(arr[0], opt + '[]', outArr);
                } else {
                    outArr.push(opt + '[]');
                }
            } else if (typeof obj[prop] == "object" && obj[prop] !== null) {
                    outArr.push(opt + '{}');
                    analyzeJson(obj[prop], opt + '{}', outArr);
            } else {
                if (obj.hasOwnProperty(prop) && typeof obj[prop] != 'function') {
                    outArr.push(opt);
                }
            }
        }
    }

    function logBeautifiedDotNotation(arr) {
        retStr = '';
        arr.map(function (item) {
            let dotsAmount = item.split(".").length - 1;
            let dotsString = Array(dotsAmount + 1).join('    ');
            retStr += dotsString + item + '\n';
            console.log(dotsString + item)
        });
        return retStr;
    }
}

jsonAnalyze(theJson);
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07",  "postalCode": "75007", "countryCode": "FRA",  "countryLabel": "France" };

document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);

如果以HTML显示,则应添加应答器<pre></pre>

document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"

例子:

var jsonObj={“streetLabel”:“Avenue Anatole France”,“city”:“Paris 07”,“postalCode”:“75007”;document.getElementById(“result before”).innerHTML=JSON.stringfy(jsonObj);document.getElementById(“resultafter”).innerHTML=“<pre>”+JSON.stringify(jsonObj,未定义,2)+“</pre>”div{float:left;clear:both;margin:1em 0;}<div id=“result before”></div><div id=“result after”></div>