json-viewer

谷歌浏览器直接打开json格式内容的接口地址,可以格式化显示接口返回值,保留key的双引号,支持图片链接预览

当前为 2020-01-15 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         json-viewer
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  谷歌浏览器直接打开json格式内容的接口地址,可以格式化显示接口返回值,保留key的双引号,支持图片链接预览
// @author       sgd
// @match        *://*/*
// @grant        none
// @require      https://code.jquery.com/jquery-3.4.1.min.js
// @icon         https://www.easyicon.net/api/resizeApi.php?id=501159&size=128
// ==/UserScript==

// jquery.json-viewer 插件 开始
(function($){
    /**
   * Check if arg is either an array with at least 1 element, or a dict with at least 1 key
   * @return boolean
   */
    function isCollapsable(arg) {
        return arg instanceof Object && Object.keys(arg).length > 0;
    }

    /**
   * Check if a string represents a valid url
   * @return boolean
   */
    function isUrl(string) {
        var regexp = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
        return regexp.test(string);
    }

    /**
   * Transform a json object into html representation
   * @return string
   */
    function json2html(json, options) {
        var html = '';
        if (typeof json === 'string') {
            /* Escape tags */
            json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            if (isUrl(json))
                html += '<a href="' + json + '" class="json-string">"' + json + '"</a>';
            else
                html += '<span class="json-string">"' + json + '"</span>';
        }
        else if (typeof json === 'number') {
            html += '<span class="json-literal">' + json + '</span>';
        }
        else if (typeof json === 'boolean') {
            html += '<span class="json-literal">' + json + '</span>';
        }
        else if (json === null) {
            html += '<span class="json-literal">null</span>';
        }
        else if (json instanceof Array) {
            if (json.length > 0) {
                html += '[<ol class="json-array">';
                for (var i = 0; i < json.length; ++i) {
                    html += '<li>';
                    /* Add toggle button if item is collapsable */
                    if (isCollapsable(json[i])) {
                        html += '<a href class="json-toggle"></a>';
                    }
                    html += json2html(json[i], options);
                    /* Add comma if item is not last */
                    if (i < json.length - 1) {
                        html += ',';
                    }
                    html += '</li>';
                }
                html += '</ol>]';
            }
            else {
                html += '[]';
            }
        }
        else if (typeof json === 'object') {
            var key_count = Object.keys(json).length;
            if (key_count > 0) {
                html += '{<ul class="json-dict">';
                for (var key in json) {
                    if (json.hasOwnProperty(key)) {
                        html += '<li>';
                        var keyRepr = options.withQuotes ?
                            '<span class="json-string">"' + key + '"</span>' : key;
                        /* Add toggle button if item is collapsable */
                        if (isCollapsable(json[key])) {
                            html += '<a href class="json-toggle">' + keyRepr + '</a>';
                        }
                        else {
                            html += keyRepr;
                        }
                        html += ': ' + json2html(json[key], options);
                        /* Add comma if item is not last */
                        if (--key_count > 0)
                            html += ',';
                        html += '</li>';
                    }
                }
                html += '</ul>}';
            }
            else {
                html += '{}';
            }
        }
        return html;
    }

    /**
   * jQuery plugin method
   * @param json: a javascript object
   * @param options: an optional options hash
   */
    $.fn.jsonViewer = function(json, options) {
        options = options || {};

        /* jQuery chaining */
        return this.each(function() {

            /* Transform to HTML */
            var html = json2html(json, options);
            if (isCollapsable(json))
                html = '<a href class="json-toggle"></a>' + html;

            /* Insert HTML in target DOM element */
            $(this).html(html);

            /* Bind click on toggle buttons */
            $(this).off('click');
            $(this).on('click', 'a.json-toggle', function() {
                var target = $(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
                target.toggle();
                if (target.is(':visible')) {
                    target.siblings('.json-placeholder').remove();
                }
                else {
                    var count = target.children('li').length;
                    var placeholder = count + (count > 1 ? ' items' : ' item');
                    target.after('<a href class="json-placeholder">' + placeholder + '</a>');
                }
                return false;
            });

            /* Simulate click on toggle button when placeholder is clicked */
            $(this).on('click', 'a.json-placeholder', function() {
                $(this).siblings('a.json-toggle').click();
                return false;
            });

            if (options.collapsed == true) {
                /* Trigger click to collapse all nodes */
                $(this).find('a.json-toggle').click();
            }
        });
    };
})(jQuery);
// jquery.json-viewer 插件 结束

(function() {
    'use strict';
    // 添加样式
    var style = document.createElement("style");
    style.type = "text/css";
    var text = document.createTextNode("body{margin-bottom: 200px;}per{margin:20px;}#btn{position: fixed;top: 20px;right: 20px;background-color: transparent;border: 1px solid rgb(218, 220, 224);border-radius: 4px;box-sizing: border-box;color: rgb(26, 115, 232);cursor: pointer;line-height:30px;}#btn:hover{background-color:rgb(210, 227, 252);}   ul.json-dict, ol.json-array {list-style-type: none;margin: 0 0 0 1px;border-left: 1px dotted #ccc;padding-left: 2em;}.json-string {color: #0B7500;}.json-literal {color: #1A01CC;font-weight: bold;}a.json-toggle {position: relative;color: inherit;text-decoration: none;}a.json-toggle:focus {outline: none;}a.json-toggle:before {color: #aaa;content: \"\\25BC\";position: absolute;display: inline-block;width: 1em;left: -1em;}a.json-toggle.collapsed:before {transform: rotate(-90deg);-ms-transform: rotate(-90deg);-webkit-transform: rotate(-90deg);}a.json-placeholder {color: #aaa;padding: 0 1em;text-decoration: none;} a.json-placeholder:hover { text-decoration: underline; }");
    style.appendChild(text);
    var head = document.getElementsByTagName("head")[0];
    head.appendChild(style);

    var source =  $('pre[style="word-wrap: break-word; white-space: pre-wrap;"]');
    // 如果是直接打开的json接口地址才需要格式化插件
    if(source.length > 0){
        source.attr("id", "json-source")
        source.hide();
        var src = source.html();// 获取到内容
        // 添加一个格式化显示的per元素
        $("body").append($('<per id="json-renderer"></pre>'))
        console.log(src);
        // 将内容用eval函数处理下
        var input = eval('(' + src + ')');
        // 调用格式化方法,参数:是否收缩所有的节点    是否为Key添加双引号
        $('#json-renderer').jsonViewer(input, {collapsed: false,withQuotes: true});

        // 添加原文、格式化后内容的切换按钮
        $("body").append('<input type="button" value="View Source" id="btn"/>');
        $("body").on("click","#btn",function(){
            var v = $(this).val();
            if(v=='View Source'){
                $(this).val("Format Content");
                // 查看原文
                $('#json-renderer').hide();
                $('#json-source').show();
            }else{
                $(this).val("View Source");
                // 格式化
                $('#json-renderer').show();
                $('#json-source').hide();
            }
        });

        // 所有a标签,看是否是图片,是图片生成预览图
        $(document).on("mouseenter mouseleave","a.json-string",function(event){
            if(event.type=='mouseenter'){
                // 移入
                var href = $(this).attr('href');
                if(isImg(href)){
                    $("body").append('<div style="display:none; position: absolute;width:300px;height:200px;" class="preview"><img style="width:100%;height:100%;" src="'+ href +'" /></div>');
                    var xPos = parseInt(event.pageX) + "px";
                    var yPos = parseInt(event.pageY) + "px";
                    $(".preview").css("left", xPos);
                    $(".preview").css("top", yPos);
                    $(".preview").show();
                }
            }else{
                // 移除
                $(".preview").remove();
            }

        });
    }

    /*检查是否是图片链接*/
    function isImg(pathImg) {
        var regexp = /^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?\/([\w#!:.?+=&%@!\-\/])*\.(gif|jpg|jpeg|png|GIF|JPG|PNG)([\w#!:.?+=&%@!\-\/])?/;
        return regexp.test(pathImg);
    }

})();