jsonp库解读与分析

jsonp是一个经典的跨域解决方案,虽然现在使用的很少,但是这种经典的解决方案还是应该了解下,最近在看github中开源的jsonp库,跟着源码加上查阅资料了解了一下jsonp前后端主要的工作,借此来分享一下,有不对的地方大家可以留言指出。

前端需要传递的内容

  • 访问的服务器方法名

  • 返回json前端调用方法

服务器需要完成的内容

按照前端给的回调函数名包裹成字符串返回

解析github的jsonp项目

传递参数

使用这个库需要传递三个参数

  • url

访问的服务器函数

  • opt

    1. name:本地接受服务器返回json的函数名称的

    2. param、preffix 服务器解析请求并返回json的函数名称与接受服务器返回json的函数名称前缀

    3. timeout 等待服务器返回结果的最长时间

  • fn

你希望执行的回调函数

分析jsonp库代码

发起jsonp请求


        var target = document.getElementsByTagName('script')[0] || document.head;

        script = document.createElement('script');

        script.src = url;

        target.parentNode.insertBefore(script, target);

代码很简单就是在本地创建script然后发起url请求

处理等待最大时间方法


if (timeout) {

            timer = setTimeout(function(){

                cleanup();

                if (fn) fn(new Error('Timeout'));

            }, timeout);

        }

jsonp库在发起请求前首先执行这部分代码,当在给定的时间内这个定时器没有清楚就会执行清理函数,这里这里值得注意的是,如果有回调函数也会给回调函数抛一个错误。

清理函数

写通用工具方法,要记得写清理方法处理不再使用的元素,避免浪费资源


  function cleanup(){

            if (script.parentNode) script.parentNode.removeChild(script);

            window[id] = noop; // 将处理服务器返回数据函数赋值为空函数

            if (timer) clearTimeout(timer);

        }

  • 首先清理了发起jsonp请求的script标签

  • 接着清理监听等待函数返回最大时间的定时器

  • 并将本地监听函数设置为空函数。

监听服务器返回


window[id] = function(data){

            cleanup(); // 不要忘记清理

            if (fn) fn(null, data);

        };

在window对象上监听远端返回,这个id就是前边设置的参数组装而成的,这里要注意一下这里不能完了执行清理函数,以防资源浪费

服务器处理部分


 const pathName = url.parse(req.url).pathname; // 获取访问服务器的函数名称

        const queryData = qs.parse(req.url.split('?')[1]); // 获取请求参数部分

        if (pathName === '/jsonp' && queryData['callback']) {

            res.writeHead(200, {

                'Content-Type': 'application/json;charset=utf-8' // 返回类型为json

            });

            var data = {

                name: 'zhouyijun'

            }

            res.end(queryData.callback + `(${JSON.stringify(data)})`) // 返回值,要记得将json对象转换为字符串

        }

这里代码比较简单就是通过url解析参数,分发给对应的处理函数,并且取出终端回调函数名称使用字符串拼接成结果返回给终端。

jsonp GitHub地址

你可能感兴趣的:(jsonp库解读与分析)