• 手把手教你写一个JSON在线解析的前端网站1


    前言

    作为一名Android开发,经常要跟后端同事联调接口,那么总避免不了要格式化接口返回值,将其转换为清晰直观高亮的UI样式以及折叠部分内容,方便我们查看定位关键的信息。

    一直以来都是打开Google 搜索json格式化关键字,然后选择Google推荐的前三名的网址,比如

    在这里插入图片描述

    bejson网站:
    https://www.bejson.com/

    json.cn网站:
    https://www.json.cn/

    开源中国的JSON解析:
    https://tool.oschina.net/codeformat/json

    我自己搞的小网站在Google搜索上还排不上号,这里王婆卖瓜,自卖自夸一下,也分享一下子。

    json2.top网站:
    https://www.json2.top/

    之前用的多,基本是直接json.cn来解决问题。现在用自己搭建的json2.top,感觉更爽一些😂。

    技术实现

    json2.top这个站点完全是一个前端项目,不涉及一点后端相关的技术。纯jQuery来实现的。实现部分参考了一下json.cn,应该说参考的部分比较多,搬运了不少他们的代码,但是最核心的逻辑还是自己完善思考出来的。

    先来看看效果

    在这里插入图片描述

    在左侧输入JSON数据,右侧自动会对左侧的数据进行格式化转换, 变得规整清晰,代码高亮,还能够折叠。特别方便开发者专注于自己的核心数据。

    接下来我们来具体讲讲如何实现这个功能,先从代码格式化来开始吧,折叠的部分可以放在后面。

    先提前把需要的jQuery.js文件等引入好.

    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    
    • 1

    然后准备两个div,用于放左侧的输入区域的内容,以及右侧格式化好的内容,具体代码如下

    <div class="container">
        <div class="split">
            <div id="split-0">
    
    <textarea id="json-src" placeholder="Please enter the JSON data... " class="form-control common-font-size"
              style="height:100%;padding:10px 10px 10px 30px;border:0;border-radius:0;resize: none;
                      outline:none;border: 1px solid #eee">textarea>
    
            div>
    
            <div id="split-1">
                <div id="right-box" class="common-font-size bg-color-ff"
                     style="width:100%;border:solid 1px #eee;border-radius:0;resize: none;overflow-y:scroll; outline:none;position:relative;flex: 1;flex-grow: 1;">
                    <p class="editor-tip">Click on key and value to editp>
                    <div id="hidden-message-box" class="alert alert-danger alert-dismissible"
                         role="alert"
                         style="display:none;margin-bottom:0;padding:10px 2vw;font-size: calc(var(--target) + 4px);">
                        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                            <span aria-hidden="true">×span>
                        button>
                        <p><i class="fa fa-bell" aria-hidden="true">i>
                            tips:
                            <span id="hidden-message">
                          Default warning
                      span>
    
                        p>
                    div>
                    <div id="line-num"
                         style="background-color:#fafafa;padding:0px 8px;float:left;border-right:dashed 1px #E5EBEE;display:none;color:#999;position:absolute;text-align:center;over-flow:hidden;">
                    div>
                    <div class="ro" id="json-target"
                         style="padding:0px 32px;white-space: pre-line;word-wrap:break-word;">div>
                div>
            div>
        div>
    
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    下面是核心逻辑。
    当我们在浏览器上粘贴了没有被格式化过的JSON数据后,我们的思路是先对这个JSON数据先解析,这里先不考虑容错问题,非JSON格式的数据等,只关注最关键的。

    默认就用js提供的const obj = JSON.parse(content);来解析json字符串,如果这个json合法,那么我们会得到一个obj的对象,具体这个对象里面的内容都有啥,还需要进一步判断。

    没有专门深究过js这门语言,不过总感觉js的类型比较多,又弱语言类型,判断obj具体是什么样的类型就比较无奈。

    就以截图中左侧的内容为例来分析吧

    {    "sites": [    { "name":"JSON Online Parse" , "url":"www.json2.top" },     { "name":"Google" , "url":"www.google.com" },     { "name":"Introducing JSON" , "url":"www.json.org" }    ]}
    
    • 1

    我们得到的obj是一个map结构,也可以说是是Java里面的对象object,可以理解为obj: {} 在js代码中判断object,用这样的判断typeof obj === "object"

    接着在看, sites的结构是个数组,site:[] ,那么在js代码中如何判断数组,用这样的代码Array.isArray(site).

    接着以"name":"JSON Online Parse"讲解,解析判断到这一步了,这个是site数组中的第一个对象,然后会对这个对象进行细分判断,取出对应的key"name", value"JSON Online Parse",因为在做格式化这一步,我们需要细分的比较细,那么会取出value,来判断value的类型,到了这一步,value已经算是原子类型了,没法在细分了(原谅我用Java语言的说法来描述), 那么如何判断"JSON Online Parse"是什么类型呢,我们明显能看出来,它是个string类型, 就用typeof obj === "string"来判断字符串吧.

    由于这个例子没有数字,bool,以及null 那么目前的判断还是不够完善的.
    判断数字的代码为typeof obj === "number"
    判断bool的代码为typeof obj === "boolean"

    字符串为“”以及null的都需要处理分别是obj === "" 以及 obj === null

    上面涉及到的几大类型都介绍到了,那么就还是以上文的json数据,来编写代码吧,上文有讲到这个需要一层层的解析,那么可以想象的到,代码是个递归的逻辑,会出现循环调用的情况。

    下面是完整的逻辑

    function stringifyToHtml(obj, level) {
            if (obj === null) {
                return "null";
            } else if (obj === "") {
                return "\"\"";
            } else if (Array.isArray(obj)) {//说明是数组结构
                //console.log(obj);
                var str = " + obj.length + "\">" +
                "" + "[
    "
    ; var blank = generateBlank(level); if (obj.length > 0) { for (let i = 0; i < obj.length; i++) { const item = obj[i]; var json_value = stringifyToHtml(item, level + 1); if (i == obj.length - 1) { json_value += "
    "
    ; } else { json_value += ",
    "
    ; } str = str + blank + json_value; //console.log(item); } } str += generateBlank(level - 1) + "]"
    ; return str; } else if (typeof obj === "object") {//是一个object类型 var str = "" + "" + "{
    "
    ; var blank = generateBlank(level); const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = obj[key]; var json_key = "\"" + key + "\"" + ": "; var json_value = stringifyToHtml(value, level + 1); if (i === keys.length - 1) { json_value += ""; } else { json_value += ",
    "
    ; } str = str + blank + json_key + json_value; } str += "
    "
    + generateBlank(level - 1) + "}"
    ; return str; } else if (typeof obj === "number") { return "" + obj + ""; } else if (typeof obj === "boolean") { return "" + obj + ""; } else if (typeof obj === "string") { return "\"" + obj + "\""; } else { return "" + obj; } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    我们还是以前文的json数据来分析,下面会再贴一遍的

    {    "sites": [    { "name":"JSON Online Parse" , "url":"www.json2.top" },     { "name":"Google" , "url":"www.google.com" },     { "name":"Introducing JSON" , "url":"www.json.org" }    ]}
    
    • 1

    在经过JSON.parse(content)处理后,我们得到了一个obj对象,接着需要判断当前obj具体是什么类型,是对象,还是数组,或者是原子类型(number,bool,string,null等类型)。所以在stringifyToHtml()这个函数体的内部,就是根据这些具体的类型来进一步处理的,每一个类型都有对应要展示出来的形式以及存在递归逻辑。在原子类型里面,基本就是展示处理了,只需要做好颜色样式展示,这个可以给定好css样式形式比如className,自己对具体的className编写对应的高亮效果啊就好了。在对象类型以及数组类型中,都还需要进行递归的逻辑。

    比如说,刚拿到上面的那串字符串解析好的obj对象,判断它是对象类型后,就需要对齐进行拆分为两部分,key,value,格式化输出是要对key, value都做处理的,key就直接当做字符串展示出来就好,这里用的是var json_key = "\"" + key + "\"" + ": ";这样的代码展示的,key也有自己的样式效果。然后就是value了,在对value处理的时候,也是要进行递归判断的,因为拿到的这个value,它的结构是个数组,如果不是用这个例子的话,它还可能是个对象,原子类型等等。另外由于对象类型存在多个key,value,所以在判断是对象类型后,还需要for循环这个对象类型呢,具体就参考else if (typeof obj === "object")这个分支判断的内部逻辑了,里面代码写的比较细致。仔细看,就能看懂。

    接着说到,在拿到sites是个数组结构后,我们需要开始对sites这个数组结构进行格式化解析展示,处理对应的样式换行等等啊,换行这里不讲。同样先判断Array.isArray(obj)是数组,然后处理最外层的[]中括号符号,这个数组呢,也是需要for循环遍历的,遍历过程中,也存在递归情况。

    这两块复杂的讲完了,剩下的都是原子类型啦,只需要取出对应的值,展示对应的样式效果就好了,代码特别简单。参考上文完整的代码吧。

    最后

    把上述代码整理后,放到了github上的仓库上,地址是https://github.com/xingstarx/jsonParseDemo

    github上的项目支持用vercel部署的,这样就可以得到一个属于自己的在线解析工具啦。

    直接访问这个https://www.json2.top/也可以,核心代码是一样的,只不过前端样式丰富了一些。

    本文内容同步自个人博客站点xingstarx.top 欢迎围观,目前内容还不算多😂

  • 相关阅读:
    python (语音)信号拆分为数据块,计算短期能量和过零率
    【无标题】
    体细胞杂交第六弹!worthington组织培养术语终章
    flex布局独占一行实现方法
    【Python爬虫】urllib库——尚硅谷
    CS学习记录-探测_提取配置
    【计算机图形学】期末考试课后习题重点复习(第3-4章)
    Qt OpenGL(二十三)——Qt OpenGL 核心模式-给三角形上色
    Mybatis中 collection 和 association 标签 的区别
    论文阅读 Dynamic Graph Representation Learning Via Self-Attention Networks
  • 原文地址:https://blog.csdn.net/xxx823952375/article/details/133788657