超简单的实现一个jsonp库

需求

在调用QQ音乐搜索歌曲api的时候发现返回是一个jsonp

请求url:
https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg?format=jsonp&key=周杰伦&jsonpCallback=call&format=jsonp
返回:call({xxx})


call是根据我们传递的jsonpCallback的值决定的

实现

我希望有一个jsonp对象,可以这样使用

new Jsonp({
  url: 'http://xxxx',
  callBackname: 'call',
  success: function(result){
    //处理数据
  }
});
完整代码
//基本结构
!(function(window){
  function Json(param){
   //初始化参数
       let ele = document,
       script = ele.createElement('script'),
       result = null,
       _url = param.url || '',
       _success = param.success || function () { },
       _error = param.error || function () { };
                
        if( !param.callbackName ){ throw new Error('callbackName is required!');}
        window[param.callbackName] = function(){ result = arguments[0]; };

        ele.getElementsByTagName('head')[0].appendChild(script);

       script.onload = script.readystatechange = function () {
           if (!script.readyState || /loaded|complete/.test(script.readyState)) {
               _success(result);
               script.onload = script.readystatechange = null;
               }else{
                   _error();
              }
      }         
     script.src = _url;
  }
  window.Jsonp = Jsonp;
})(window);
测试(调用QQ音乐搜索API)
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        *{margin: 0;padding: 0}
        table{
            width: 100%;
            text-align: center;
            border-spacing: none;
            border-collapse: collapse;
            border: 1px solid #eee;
            line-height: 45px;
        }
        .container{
            width: 500px;
            margin: 100px auto;
        }
        td,th{
            border: 1px solid #eee;
        }
        input{
            margin-top: 10px;
            width: 100%;
            height: 35px;
            line-height: 35px;
            border: 1px solid #eee;
            outline: none;
            text-indent: 5px;
        }
    </style>
</head>
<body>
    <div class="container">
        <table>
            <thead>
                <caption>QQ音乐搜索API调用</caption>
                <tr>
                    <th>id</th>
                    <th>name</th>
                    <th>singer</th>
                </tr>
            </thead>
            <tbody id="result">
                
            </tbody>
        </table>
        <div>
            <input id="key" type="text" placeholder="歌曲或者歌手...">
        </div>
    </div>
    
    <script>
        !(function (window) {

            function Jsonp(param) {
                let ele = document,
                    script = ele.createElement('script'),
                    result = null,
                    _url = param.url || '',
                    _success = param.success || function () { },
                    _error = param.error || function () { };
                
                if( !param.callbackName ){ throw new Error('callbackName is required!'); }

                window[param.callbackName] = function(){ result = arguments[0]; };

                ele.getElementsByTagName('head')[0].appendChild(script);

                script.onload = script.readystatechange = function () {
                    if (!script.readyState || /loaded|complete/.test(script.readyState)) {
                        _success(result);
                        script.onload = script.readystatechange = null;
                    }else{
                        _error();
                    }
                }
                
                script.src = _url;
            }

            window.Jsonp = Jsonp;

        })(window);

        document.getElementById('key').addEventListener('keyup',function(){
            let key = document.getElementById('key').value;
            new Jsonp({
                url: `https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg?format=jsonp&key=${key}&jsonpCallback=call&format=jsonp`,
                callbackName: 'call',
                success: function (result) {
                    if (result) {
                        render(result);
                    }
                },
                error: function(){
                    console.log('error');
                }
            });
        },false);

        

        function render(result){
            console.log(result);
            let dom = document.getElementById('result');
            let tmp = '';
            
            result.data.song.itemlist.forEach(ele => {
                tmp += `<tr><td>${ele.id}</td><td>${ele.name}</td><td>${ele.singer}</td></tr>`;
            });
            dom.innerHTML = tmp;
        }
    </script>
</body>
</html>
思路

1.初始化参数
2.绑定call事件(服务器返回的函数调用)来获取返回值
3.动态创建script标签
4.script加载完成后进行回调success并把返回值传递出去
5.加载失败则回到error

本人小白一枚,代码很烂,没有处理请求参数,/捂脸 打包了在github
https://github.com/TankCJZ/JsonpDemo

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,079评论 19 139
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,949评论 0 38
  • 消费人群定位
    Monique7阅读 160评论 0 0
  • 花开两朵,各表一枝。我言天方,君说咫尺,折翅飞翔,幽在梦想。时与空合,谓为宇宙,恐在其中,不知所谓。
    秋落鸣蝉阅读 87评论 0 1
  • 词汇 the press and public were atwitter, anticipating that'...
    谷音sp阅读 387评论 0 0