实用小工具(持续更新)

JWT##


一种可以把token保存在cookie中的前端会话解决方案。相对于传统的session,它有效的减轻了后端的存储和随之而来的增删改查的压力。但相应的,由于是保存在前端cookie中,处于对其安全性的考量,加密/解密的过程会带来一定的服务器压力。
其构成分为三部分:
header

{ typ:"jwt", alg:"HS256" }

可以看出,头部用来保存两个信息:token的类型和其加密的算法。
claims(payload)

{
    iss:"temp.com",
    sub:"uid123",
    exp:"123456789",
    iat:"123456789",
    jtd:"hiy5td656fifs85yd"
}

jwt的实体,保存了这个jwt的发布者(iss),其实就是这个站点标识;操作的对象,也称之为这个jwt的主题(sub),我在操作的时候保存的是用户id,不过鉴于其json的数据存储形式,我觉得直接保存用户对象也何尝不可(以后可以尝试一下)。既然描述的是主题,那么意味着这其中也应当填写操作的动词(究竟干了什么);这个jwt的创建时间(iat)和过期时间(exp),这个没什么好说的,但是后端的过期逻辑得注意一点,不然时间间隔太久,这一块的测试工作可能会遗漏(我就是,写了两块登陆状态的判断逻辑,结果其中一块有bug,直接导致流程来回跳转不停,一边提示未登录,一边提示已登陆);由于我是使用的jwt模块,所以未给出jtd(jwt的id)这个参数,可能模块帮助我生成了(官网上我已经找不到这个字段的说明了)。
signature

    const sig = [
        encode(header),
        encode(claims)
    ].join(".");
    const signature = identifiedAlg(sig + secret);

有效性验证块,一般拿前面两块的encode字段配合服务器给出的secret的标识同时加密所得,主要用于jwt的恶意篡改。
组合
三块内容各自按照指定算法加密之后,用"."字符连接起来作为jwt发送给客户端。在客户端中,jwt会已httponly的状态保存在cookie中(httponly:无法通过js访问和修改),每次向指定站点发送请求的时候(一般也是这个jwt的发布者),这个jwt都会写在请求头中发送给服务器做数据验证。

dataTable##


一个基于jquery的表格拓展工具,支持多种动态表格功能的使用和开发,高度自定义选项。不过需要引用自己指定的jquery(用前端框架的话),因而会对其他前端工具有覆盖,建议独立出去,然后再以模块的形式引入。
使用过程很简单,首先需要在页面定义一个table,并提供一种方式访问:

id 名字 单位

之后调用dataTable为jquery添加的接口dataTable/DataTable即可,当然,如果使用的是前端框架,则需要保证在生成页面之后调用接口。

    $("#dataTable").DataTable();

dataTable提供了两个版本的接口(dataTable和DataTable),两者的不同之处在于其返回值,dataTable返回的是$("#dataTable"),而DataTable返回的是表的API,可以用来做一些特殊的修改,之后我们会用到。

这样操作完之后,应该就能在页面上显示一个0参数的dataTable表格了。
表格的作用是用来呈现数据,dataTable允许我们直接把数据填写进表格中,或者定义成js数组,但这在实际生产过程中是不太现实的。绝大多数的数据都会以ajax请求返回值的形式发送给dataTable,因此,我们需要在调用接口的时候给出指定的参数

    $("#dataTable").DataTable({
        ajax: "/json/data.txt"
    });

这样,我们就可以获取到本地服务器静态目录json下的data.txt文件了。这里除了填写url之外,我们还可以填写完整的ajax参数表,即

    $("#dataTable").DataTable({
        ajax: {
            url: "/json/data.txt",
            data: {
                from: 0,
                to: -1,
            }
        }
    });

dataTable的ajax和jquery的基本一样,但是有个参数需要特别注意,即dataSrc,这个参数的意义在于指定这个返回值的key,比如一般的json返回为:{data: [...]},那么这时候就需要指定dataSrc为"data"了。当然如果不指定,dataSrc的默认值就是"data";如果没有键值,则指定空字符串;如果返回的是XML格式,也可以将dataSrc定义为函数function(json) { ... }以便进行转化。

在ajax中也可以定义success用于接受传过来的结果,不过这貌似会替换dataTable自身的处理函数,所以可以用success检测返回值正不正确,但检测完毕之后应当将处理权交由dataTable。

数据收到后第二步就是应该做项绑定了,传统的ejs方式是做一个循环,根据数据的多少生成多少tr。dataTable提供了列绑定的功能,可以处理简单的数据填充

    //  假设返回的数据是 
    //  { data: [ { id: 123, name: "张三", company: [ { name: "煎饼果子学院" } ] } ] }
    $("#dataTable").DataTable({
        ajax: "/json/data.txt",
        columns: [
            {data: "id"},
            {data: "name"},
            {data: "company.0.name"}
        ]
    });

这里,数据是按照列数组的顺序依次绑定的,我们这边还演示了嵌套对象和嵌套数组的处理方法。
数据如果都是这样依次填入的,那我们的工作会很轻松。但实际需求往往会复杂的多:比如想在每行表格的最后一个表格显示一组操作按钮、比如在第一列设定自增长的行ID、比如某列数据是结果中几个参数共同计算的结果。面对那样的情况,简单的列指定是不够的,因此dataTable提供了createdRow回调函数来让我们在数据填充完之后,对每行数据进行进一步的修改

    $("#dataTable").DataTable({
        ajax: "/json/data.txt",
        columns: [
            {data: "id"},
            {data: "name"},
            {data: "company.0.name"}
        ],
        createdRow: (row, data, index) => {
            const td0 = $("td", row).eq(0);
            td0.html(index);

            const td4 = $("td", row).eq(4);
            td4.html("");
            td4.append("");

            const td3 = $("td", row).eq(3);
            const staffNum = data.company[0].managers.length + data.company[0].workers.length;
            td3.html(String(staffNum));
        }
    });

随着jquery的介入,表格的排版可以变得异常灵活。
行的修改我们用createdRow,表其他部分的修改怎么办呢?比如修改表头。这里我们使用initComplete属性(在初始化完成之后),下面这个例子就是为表头添加下拉列表:

initComplete: (settings, json) => {
    //  还记得之前说过的dataTable()和DataTable()的区别吗?这里的话如果之前
    //  初始化时用的是DataTable,则其返回值就是api
    const api = $("#dataTable").dataTable().api();
    api.columns().indexes().flatten().each((i) => {

        //  用于指定列的表头生成下拉列表,如果不加这个判断,则所有的th都会包含过滤用的下拉列表
        if (i !== 2) { return; }
        const column = api.column(i);

        //  这里就是jquery表现的时候了,我们往这个列的列头中append一个select
        const select = $("")
            .appendTo($(column.header()))
            .on("change", (event) => {
                //  如果下拉表发生了变化,则把选中的项的value作为查询的key组装成正则表达式
                //  交给列查询之后重绘
                const vlu = $.fn.dataTable.util.escapeRegex($(event.target).val());
                column.search(vlu ? "^" + vlu + "$" : "", true, false).draw();
            });

        //  对该列的数据做group筛选掉重复的,然后排序之后插入select
        column.data().unique().sort().each((d, j) => {
            select.append("");
        });
    });
}

这个例子相对复杂,但通过它,可以有很多拓展的方向。initComplete函数意味着在表绘制完成之后可以进行很多操作(虽然之后用jquery选择器也可以,但从整体的角度来看,在这里面写比较合理);下拉列表可以对列进行操作,那么意味着我们也可以设置其他空间来对列里的项进行整体操作。
至此,对表,我们可以做到随意修改了。但同时会发现,除了表,dataTable会帮我们生成一些其他组件:每页显示的项数、查找框、信息、分页。这些东西也可以通过设置初始化参数来操作,我们可以分配给dataTable一个dom属性,该属性是一个字符串,dataTable的设计者开发了一组简易的组件标识,然后配合类似于xml的结构组装起来,便可以对表以及表四周的这一套组件进行定位了

    //  <> - 代表一个div,可以指定类和id,id的指定和jquery一样:#id,不同的是类,
    //    类单独存在的时候,类不需要在类名前加【.】
    //  l - Length changing 每页显示多少条数据选项
    //  f - Filtering input 搜索框
    //  t - The Table 表格
    //  i - Information 表格信息
    //  p - Pagination 分页按钮
    //  r - pRocessing 加载等待显示信息
    
    //  最近写的dataTable模板用的dom(左上角指定id的div是用来存放新建按钮的)
    dom: "<'row'<'#btnCreateBtn.col-md-1'>><'row'rt><'row'p>"

可以选择dataTable是否生成某些组件,也可以绑定监听组件的触发事件

    //  是否生成组件的选项(设置true/false)
    //  paging:分页
    //  ordering:表头排序
    //  info:表信息
    //  searching:查找
    //  lengthChange:页长

    //  组件事件(用on来监听,表相关的需要追加dt命名空间)
    //  page:翻页事件
    //  length:选择单页显示的项数
    //  search:查找框变化事件
    //  processing:请求过程中间事件
    table.on("search.dt", (e, settings) => {
        console.log(table.search());
    });

bootstrap-datepicker##

你可能感兴趣的:(实用小工具(持续更新))