Jsonp的讲解及封装

Jsonp的讲解及封装

Posted by limantang on August 25, 2018

Jsonp

前端与后端的交互绝大部分都是通过ajax进行数据的传递和接受,但是ajax不能突破同源限制,简单来讲同源限制 域名,端口号都相同就是同源,除此以外就是非同源, 这个限制是浏览器出于安全考虑强行添加,但是有时候出于业务上的需求或者其他因素,我们必须突破同源限制获取数据 但是这个时候ajax就不能满足要求了,我们需要采用其他办法来解决问题

突破同源限制的办法之一就是Jsonp,为什么叫Jsonp呢,我也不知道…, 可能是数据交互的主要格式是json吧,我们不应该被这个jsonp中的json所限制住,或者说不要被这个json所影响 其实只要是满足js函数语法的数据都是可以传递的

为什么这样说呢,因为使用Jsonp来跨域的主要原理就是利用了script标签的跨域能力, 只要带有src属性的标签都具备这个能力(总感觉是src具备这个能力呢QAQ) Jsonp的大体过程就是我们事先定义好一个callback,然后和我们对应的后端商定好callback的名字, 然后对应的后端在我们请求回来的script标签里面添加这个callback执行的语句callback() 这个函数所接受的参数就是我们要使用的数据,然后我们在前端定义好一个同名的数据处理函数,到这里就算结束了, 其实原理还是蛮简单的

有一点我们要注意这个callback不要和我们其他的函数同名,要不然可能会产生影响

下面就简单的封装一个Jsonp

 getJsonp = (url, callback = 'callback') => {
    let result; //  定义结果数据--->1
    return new Promise((resolve, reject) => {
        let sameNameCallback;   //  预定义可能会存在的和callback同名的函数的临时变量--->2
        const script = document.creatElement('script'); //  创建script标签--->3
        script.src = url;//--->4
        script.onload = () => {
        //  当script加载完毕之后,如果我们在上面定义,下面赋值的sameNameCallback还是undefined得话,说明不存在这个同名函数,就将
        //  下面定义在window下面的callback删除掉,防止影响以后其他函数的定义
            if (sameNameCallback === undefined) { //--->7
                delete window[callback]
            } else {
            //  如果sameNameCallback存在就说明代码之前存在和我们所定义的callback同名的函数
            //  那么我们下面存储的sameNameCallback就派上用场了,可以将sameNameCallback重新赋值给window下面的那个同名函数
            //  这样不会影响到其他的代码
                window[callback] = sameNameCallback;
            }
            resolve(result);
        }
        sameNameCallback = window[callback];//--->5    //  将这个可能会存在的同名函数存到上面定义的变量中
        window[callback] = (data) => {  //定义我们自己的callback函数,这个时候不必担心会覆盖和callback的同名函数,因为我们上面以及存好了
            result = data;
        }//--->6
        document.head.appendChild(script)
    })
}

代码的执行步骤标注在注释之后了,按着这个执行顺序可以更好的理解这段代码

使用方法

getJsonp('www.xxx.com/yyy').then((data) => {
    //  处理这个data的代码
})