pretty-print JSON using JavaScript

后端 未结 24 1721
一向
一向 2020-11-21 06:45

How can I display JSON in an easy-to-read (for human readers) format? I\'m looking primarily for indentation and whitespace, with perhaps even colors / font-styles / etc.

相关标签:
24条回答
  • 2020-11-21 07:04

    If you're looking for a nice library to prettify json on a web page...

    Prism.js is pretty good.

    http://prismjs.com/

    I found using JSON.stringify(obj, undefined, 2) to get the indentation, and then using prism to add a theme was a good approach.

    If you're loading in JSON via an ajax call, then you can run one of Prism's utility methods to prettify

    For example:

    Prism.highlightAll()
    
    0 讨论(0)
  • 2020-11-21 07:05

    For debugging purpose I use:

    console.debug("%o", data);
    
    • https://getfirebug.com/wiki/index.php/Console_API
    • https://developer.mozilla.org/en-US/docs/DOM/console
    0 讨论(0)
  • 2020-11-21 07:05

    It works well:

    console.table()
    

    Read more here: https://developer.mozilla.org/pt-BR/docs/Web/API/Console/table

    0 讨论(0)
  • 2020-11-21 07:06

    Based on Pumbaa80's answer I have modified the code to use the console.log colours (working on Chrome for sure) and not HTML. Output can be seen inside console. You can edit the _variables inside the function adding some more styling.

    function JSONstringify(json) {
        if (typeof json != 'string') {
            json = JSON.stringify(json, undefined, '\t');
        }
    
        var 
            arr = [],
            _string = 'color:green',
            _number = 'color:darkorange',
            _boolean = 'color:blue',
            _null = 'color:magenta',
            _key = 'color:red';
    
        json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
            var style = _number;
            if (/^"/.test(match)) {
                if (/:$/.test(match)) {
                    style = _key;
                } else {
                    style = _string;
                }
            } else if (/true|false/.test(match)) {
                style = _boolean;
            } else if (/null/.test(match)) {
                style = _null;
            }
            arr.push(style);
            arr.push('');
            return '%c' + match + '%c';
        });
    
        arr.unshift(json);
    
        console.log.apply(console, arr);
    }
    

    Here is a bookmarklet you can use:

    javascript:function JSONstringify(json) {if (typeof json != 'string') {json = JSON.stringify(json, undefined, '\t');}var arr = [],_string = 'color:green',_number = 'color:darkorange',_boolean = 'color:blue',_null = 'color:magenta',_key = 'color:red';json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {var style = _number;if (/^"/.test(match)) {if (/:$/.test(match)) {style = _key;} else {style = _string;}} else if (/true|false/.test(match)) {style = _boolean;} else if (/null/.test(match)) {style = _null;}arr.push(style);arr.push('');return '%c' + match + '%c';});arr.unshift(json);console.log.apply(console, arr);};void(0);
    

    Usage:

    var obj = {a:1, 'b':'foo', c:[false,null, {d:{e:1.3e5}}]};
    JSONstringify(obj);
    

    Edit: I just tried to escape the % symbol with this line, after the variables declaration:

    json = json.replace(/%/g, '%%');
    

    But I find out that Chrome is not supporting % escaping in the console. Strange... Maybe this will work in the future.

    Cheers!

    0 讨论(0)
  • 2020-11-21 07:06
    <!-- here is a complete example pretty print with more space between lines-->
    <!-- be sure to pass a json string not a json object -->
    <!-- use line-height to increase or decrease spacing between json lines -->
    
    <style  type="text/css">
    .preJsonTxt{
      font-size: 18px;
      text-overflow: ellipsis;
      overflow: hidden;
      line-height: 200%;
    }
    .boxedIn{
      border: 1px solid black;
      margin: 20px;
      padding: 20px;
    }
    </style>
    
    <div class="boxedIn">
        <h3>Configuration Parameters</h3>
        <pre id="jsonCfgParams" class="preJsonTxt">{{ cfgParams }}</pre>
    </div>
    
    <script language="JavaScript">
    $( document ).ready(function()
    {
         $(formatJson);
    
         <!-- this will do a pretty print on the json cfg params      -->
         function formatJson() {
             var element = $("#jsonCfgParams");
             var obj = JSON.parse(element.text());
            element.html(JSON.stringify(obj, undefined, 2));
         }
    });
    </script>
    
    0 讨论(0)
  • 2020-11-21 07:07

    Unsatisfied with other pretty printers for Ruby, I wrote my own (NeatJSON) and then ported it to JavaScript including a free online formatter. The code is free under MIT license (quite permissive).

    Features (all optional):

    • Set a line width and wrap in a way that keeps objects and arrays on the same line when they fit, wrapping one value per line when they don't.
    • Sort object keys if you like.
    • Align object keys (line up the colons).
    • Format floating point numbers to specific number of decimals, without messing up the integers.
    • 'Short' wrapping mode puts opening and closing brackets/braces on the same line as values, providing a format that some prefer.
    • Granular control over spacing for arrays and objects, between brackets, before/after colons and commas.
    • Function is made available to both web browsers and Node.js.

    I'll copy the source code here so that this is not just a link to a library, but I encourage you to go to the GitHub project page, as that will be kept up-to-date and the code below will not.

    (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);
    
    0 讨论(0)
提交回复
热议问题