深入理解JSONP

403 阅读1分钟

6ece4aa4-57a4-4f84-8c41-293f77d07ef1.png

作者: 云峰 github: github.com/ihtml5

一、原理介绍

jsonp是一种需要服务器端配合的跨域技术,利用script脚本天然跨域的特性,可以访问第三方资源。服务器端收到请求后,将数据作为参数生成一个执行的函数字符,返回给浏览器。浏览器收到后执行这个函数,这样就可以访问到服务端的数据。

二、执行过程

  • 前端定义一个解析函数。例如jsonpCallback = function(data) {}
  • 通过params的形式包装jsonp请求参数,并且声明执行函数(如cb=jsonpCallback)
  • 后端获取到前端声明的执行函数(jsonpCallback),并以携带参数并且调用执行函数的方式传给前端
  • 前端加载返回资源的时候执行jsonpCallback,并且以回调函数的方式拿到返回的数据

三、注意点

  • jsonp只能进行get请求

四、代码编写

function JSONP({
    url,
    params = {
        format: 'jsonp',
    },
    callbackKey,
}) {
    JSONP.callbackId = JSONP.callbackId || 1;
    const callbackId = JSONP.callbackId;
    JSONP.callbacks = JSONP.callbacks || {};
    JSONP.callbacks[callbackId] = callbackKey;
    params[callbackKey] = callbackKey;
    const paramString = Object.keys(params)
    .map(key => `${key}=${encodeURIComponent(params[key])}`)
    .join('&');

    const script = document.createElement('script');
    script.src = `${url}?${paramString}`;
    document.body.appendChild(script);
    
    JSONP.callbackId++;

    return new Promise((resolve, reject) => {
        try {
            window[callbackKey] = function(data) {
                resolve(data);
            };
        } catch (error) {
            reject(error);
        } finally {
            script.parentNode.removeChild(script);
        }
    });
}

JSONP({
    url: 'https://y.qq.com/download/download.js',
    params: {
        format: 'jsonp' 
    },
    callbackKey: 'MusicJsonCallback'
}).then(value => console.log(value));