zoukankan      html  css  js  c++  java
  • jsonp用时间戳作为唯一标识的一个问题

    先上一段代码

    var jsonp = function (url, func, type) {
        var callback = "jsonpCallback_" + new Date().getTime() ,
            url = url + (url.indexOf( '?' ) + 1 ? '&' : '?') + 'callback=' + callback,
            s = creatElement("script", {"src": url});
        //console.log(callback,"callback")
        window[callback] = function (data) {
            func(data, type);
        };
        document.body.appendChild(s);
    }

    这是一段jsonp请求的函数,其中type是工作中需要,请忽略。用着感觉是没问题的,但是实际却遇到了一个bug。

    bug产生过程

        jsonp(url1, ajaxHandle, "xxx");
        jsonp(url2, ajaxHandle, "xxxx");

    当我连着写调用jsonp函数的时候看着貌似也没啥问题,
    jsonp里会根据时间戳生成两个不同的全局

    jsonpCallback_date1(),
    jsonpCallback_date2()

    时间戳函数。
    但是这里多数情况下会返回一样的时间戳。。。也就是说第二个url2请求函数会把第一个请求函数给覆盖了。导致第一个url1无法正常解析。

    解决办法,新增一个随机数,如果随机数也能再次惊人的重合,只能呵呵了。

    var jsonp = function (url, func, type) {
        var callback = "jsonpCallback_" + new Date().getTime() + Math.floor(Math.random() * 1000000),
            url = url + (url.indexOf( '?' ) + 1 ? '&' : '?') + 'callback=' + callback,
            s = creatElement("script", {"src": url});
        //console.log(callback,"callback")
        window[callback] = function (data) {
            func(data, type);
        };
        document.body.appendChild(s);
    }


    -----------------------------------------------------------------

    上面这个办法毕竟还是有缺陷,从逻辑上就允许出现bug,虽然概率极小,但是还是不应该,所以采用闭包的方式存储一个变量来避免出现callback函数同名的情况,详见
    var jsonp = (function () {
            var num = 0;
            function foo(url, callbackFunc){
                num++;
                var callback = "jsonpCallback_" + num,
                url = url + (url.indexOf('?') + 1 ? '&' : '?') + 'callback=' + callback,
                s = creatElement("script", {"src": url});
                window[callback] = function (data) {
                    callbackFunc(data);
                    window[callback] = null;
                };
                document.body.appendChild(s);
            }
            return foo;
        }());
    
    
    

      这样每次调用jsonp就能保证callback函数不一样了。

     
  • 相关阅读:
    asp.net mvc controller调用js
    无刷新文件上传 利用iframe实现
    Git使用
    easyui扩展
    Highcharts 多个Y轴动态刷新数据
    Android之Handler
    asp.net mvc之TempData、ViewData、ViewBag
    android之滑屏的实现
    java多线程系类:JUC线程池:05之线程池原理(四)(转)
    java多线程系类:JUC线程池:04之线程池原理(三)(转)
  • 原文地址:https://www.cnblogs.com/childsplay/p/4562932.html
Copyright © 2011-2022 走看看