1. 程式人生 > >自定義原生jsonp跨域請求

自定義原生jsonp跨域請求

由於同源策略,跨域(協議、域名、埠均相同的為同域)之間是不允許請求資源的,但是scrapt標籤不收跨域約束,如論是jQuery中的jsonp還是angularjs中的jsonp都是通過script來實現跨域請求的。

注意:
  1、跨域請求是通過get方式進行的,引數會連到url後;
  2、jsonp需要設定回撥函式,前端需要定義回撥函式,後端也需要有回撥函式的相關處理,否則請求不會成功。

jsonp自定義方法一(簡易版):

var ajax = function(params) {
        var callbackName = params.jsonp;
        window[callbackName] = function (json) {
            console.log("callback:");
            console.log(json);
        };
        var script = document.createElement('script');
        script.setAttribute("type","text/javascript");
        script.src = params.url+params.jsonp;
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(script);
    }
    ajax({
        "url":"/userInvite/saveLog.do?regKey=eUa%252Fv70AeBC2QolRKlUNJA%253D%253D&refererUrl=www.baidu.com&guid=&callback=",    // 請求地址
        "jsonp":"success_jsonpCallback",  // 回撥函式名為"success_jsonpCallback",可以設定為合法的字串
    })

jsonp自定義方法二:
var ajax = function ajax(params) {
        params = params || {};
        params.data = params.data || {};
        jsonp(params);
        // 定義jsonp方法
        function jsonp(params) {
            //建立script標籤並加入到頁面中
            var callbackName = params.jsonp;
            var head = document.getElementsByTagName('head')[0];
            // 設定傳遞給後臺的回撥引數名,可以自定義回撥函式名
            params.data['callback'] = callbackName;
            var data = formatParams(params.data);
            var script = document.createElement('script');
            head.appendChild(script);
            //傳送請求
            script.src = params.url + '?' + data;
             //建立jsonp回撥函式(傳送請求後會得到後臺結果,然後呼叫該回調函式)
            window[callbackName] = function (json) {
          //json為後臺返回的請求結果,後臺已完成該次請求的響應,之後將建立的script移除
                head.removeChild(script);
                clearTimeout(script.timer);
                window[callbackName] = null;
           //成功響應後做的處理
                params.success && params.success(json);
            };
            //為了得知此次請求是否成功,設定超時處理
            if (params.time) {
                script.timer = setTimeout(function () {
                    window[callbackName] = null;
                    head.removeChild(script);
                    params.error && params.error({
                        message: '超時'
                    });
                }, time);
            }
        };
        //格式化引數
        function formatParams(data) {
            var arr = [];
            for (var name in data) {
                arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
            }
            // 新增一個隨機數,防止快取
            arr.push('v=' + random());
            return arr.join('&');
        }
        // 獲取隨機數
        function random() {
            return Math.floor(Math.random() * 10000 + 500);
        }
    };    

//使用例項
ajax({
        "url":"/userInvite/saveLog.show",    // 請求地址
        "jsonp":"success_jsonpCallback",  // 回撥函式名為"success_jsonpCallback"
        "data": {
            "regKey":sourceType,  
            "refererUrl":referUrl|| "",
            "regGuid":cookieTest
        },
        success:function(res){   // 請求成功的回撥函式
            if(res != null){
                console.log("跨域請求成功!");
            }

        },
        error: function(error) {}   // 請求失敗的回撥函式*/
    });