JavaScript 进阶营技术干货

超简单的实现一个jsonp库

2018-04-13  本文已影响0人  TankCJZ
需求

在调用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

上一篇 下一篇

猜你喜欢

热点阅读