zoukankan      html  css  js  c++  java
  • jsonp的简单封装

    一、demo情景

      1、通过gulp在本地开启两个服务器;

      2、服务器协议相同、端口或者域名不同(通过gulp-connect设置)

      3、后台用js文件模拟后台返回数据。(仅仅只是简单的执行前台传入的函数)

    二、为封装代码写法

      1、服务器一中的 test1.js 文件

    //4、jsonp跨域
    //先定义一个callback函数,函数名要与后台一致
        function jsonp(res){
            console.log(res)
        }
    //js构建一个script标签。并将src设置为请求地址url,且通过地址栏传参格式将定义好的函数名作为参数传入后台
        var script = document.createElement("script");
            script.src = "http://localhost:8080/js/index.js?callback=jsonp";
        document.getElementsByTagName('head')[0].appendChild(script);

      2、服务器二中的 test1.js 文件

    //后台js直接执行回调函数,并将数据当作参数(只是模拟后台返回)
    //实际后台真正返回情况,并不是执行函数,而是将其拼接,用括号包裹参数类似于:callback+"("+$data+")"
      callback("我是后台数据")

    三、jsonp封装

      1、服务器一中的 test1.js 文件

        //5、jsonp封装
        function jsonpPakeage(obj) {
            //写入url地址中的函数名称,动态创建
            var callbackName = "fn"+Math.random().toString().split(".")[1];
            
            //创建一个script标签
            var scriptObj = document.createElement("script");
            
            obj.parames = obj.parames || '';
            if (typeof obj.parames == 'object') {
                var arr = new Array();
                for (var key in obj.parames) {
                    arr.push(key + '=' + obj.parames[key])
                }
                obj.parames = arr.join('&');
            }
            //设置标签的请求路径
            //像这样:http://localhost:3000/api?callback=fn153498520409635392&id=1
            scriptObj.src = obj.url + '?' + 'callback=' + callbackName + '&' + obj.parames;
            //将创建好的带请求的script标签添加到html的body中
            document.getElementsByTagName('head')[0].appendChild(scriptObj);
    
            //这里必须这样写window[callbackName];
            //如果写window.callbackName会报错没有定义
            //var one = true;
            window[callbackName] = function (res) {
                //if(one){
                    obj.success(res);
                    //删除的时候可以这样写
                    //由于请求一次会创建一个script标签和一个函数,所以每次获取到结果后就删除
                    delete window.callbackName;
                    document.getElementsByTagName('head')[0].removeChild(scriptObj);
                    // one = false
                //}
            }
        }
        //调用
        jsonpPakeage({
            url:"http://localhost:8080/js/index.js",
            parames:"",
            success:function(res){
                console.log(res)
            }
        })

      2、服务器二中的 test1.js 文件,但这里由于是用js模拟的后台,所以拿不到服务器一传过来的动态创建的callback函数名。所以测试的时候,我是将服务器一里面的callback函数名写死。(后台在测试环境下拿不到动态函数名,所以内容不变)

    //后台js直接执行回调函数,并将数据当作参数(只是模拟后台返回)
    //实际后台真正返回情况,并不是执行函数,而是将其拼接,用括号包裹参数类似于:callback+"("+$data+")"
    callback("我是后台数据")

    四、参考

      1、https://www.jianshu.com/p/0bad94e15d34

    五、测试问题

      1、测试的时候window[callback]会执行两次,测试了几次,问题有可能出在后台使用js模拟的,导致后台会执行一次callback函数。

      2、如果后台不用js模拟还出现二次执行问题,可通过设置一个变量one并判断从而禁止二次执行。(见测试代码)

    六、jsonp优劣

      优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

      缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

  • 相关阅读:
    linux系统--磁盘管理命令(二)
    linux系统--磁盘管理命令(一)
    linux系统--用户和用户组
    linux4.10.8 内核移植(四)---字符设备驱动_led驱动程序
    linux4.10.8 内核移植(三)---裁剪内核
    linux4.10.8 内核移植(二)---初步裁剪、分区修改和文件系统
    Linux 4.10.8 根文件系统制作(三)---制作yaffs文件系统
    Kotlin的面向对象入门
    Python 中的GIL
    python 虚拟环境的 安装与 使用 和修改为豆瓣源
  • 原文地址:https://www.cnblogs.com/helloNico/p/10598667.html
Copyright © 2011-2022 走看看