jsonp的原理

一、Jsonp原理简介

  1.利用的就是script的src标签没有跨域限制来实现的

    (1)script的特性:会将引用的外部文件的文本内容当做js代码来进行解析

    (2)将远程服务气的资源添加到当前路径(位置)进行解析

      (3)   json的格式:属性名必须有冒号,例如{“b”:145}

    (4)jsonp==json+padding

  2.执行的过程

    (1)前端定义一个解析函数,例如 jsonpCallback=function(res){}

    (2)通过params的形式包装script的请求参数,并且声明执行函数(如 cb=jsonpCallback)

    (3)后端获取到前端声明的执行函数(jsonpCallback),并以携带参数并且调用执行函数的方式传递给前端

    (4)前端zaiscript标签返回资源的时候就回执行jsonpCallback,并以回调函数的方式拿到返回的数据了

  3.优缺点

    (1)缺点:只能进行get请求,优点:兼容性好,在一些老的浏览器中也可以运行

  4.来看一下完整的jsonp代码

  

<script>
    function JSONP({
        url,
        params = {},
        callbackKey = 'cb',
        callback
    }) {
        // 定义本地的唯一callbackId,若是没有的话则初始化为1
        JSONP.callbackId = JSONP.callbackId || 1;
        let callbackId = JSONP.callbackId;
        // 把要执行的回调加入到JSON对象中,避免污染window
        JSONP.callbacks = JSONP.callbacks || [];
        JSONP.callbacks[callbackId] = callback;
        // 把这个名称加入到参数中: 'cb=JSONP.callbacks[1]'
        params[callbackKey] = `JSONP.callbacks[${callbackId}]`;
        // 得到'id=1&cb=JSONP.callbacks[1]'
        const paramString = Object.keys(params).map(key => {
            return `${key}=${encodeURIComponent(params[key])}`
        }).join('&')
        // 创建 script 标签
        const script = document.createElement('script');
        script.setAttribute('src', `${url}?${paramString}`);
        document.body.appendChild(script);
        // id自增,保证唯一
        JSONP.callbackId++;

    }
    JSONP({
        url: 'http://localhost:8080/api/jsonps',
        params: {
            a: '2&b=3',
            b: '4'
        },
        callbackKey: 'cb',
        callback (res) {
            console.log(res)
        }
    })
    JSONP({
        url: 'http://localhost:8080/api/jsonp',
        params: {
            id: 1
        },
        callbackKey: 'cb',
        callback (res) {
            console.log(res)
        }
    })
</script>

***注意

  encodeURI和encodeURIComment的区别

    (1)encodeURL()不会对本身属于URI的字符进行编码,例如:“/”,“:”,“#”,“?”

    (2)encodeURIcomment() 则会对他发现的任何的非标准字符进行编码,同时使用decodeURIcomment()来解码。

posted @ 2022-04-25 09:52  倚栏听风时  阅读(10381)  评论(0编辑  收藏  举报