JSONP原理及簡單實現(xiàn)

JSONP是實現(xiàn)跨域通信的解決方案

比如

<script src = "http://jsonp.js?callback=xxx"></script>

callback定義一個函數(shù)名稱,而遠程服務端通過調(diào)用指定的函數(shù)并傳入?yún)?shù)來實現(xiàn)傳遞參數(shù)

var JSONP = {

? ? ? ? // 獲取當前時間錯

? ? ? ? now: function(){

? ? ? ? ? ? ? ? return (new Date()).getTime();},

? ? ? ? // 獲取16位隨機數(shù)

? ? ? ? rand: function(){

? ? ? ? ? ? ? ? return Math.random().toString().substr(2)},

? ? ? ? // 刪除節(jié)點元素

? ? ? ? removeElem: function(elem){

? ? ? ? ? ? ? ? var parent = elem.parentNode;

? ? ? ? ? ? ? ? if(parent && parent.nodeType !== 11){

? ? ? ? ? ? ? ? ? ? ? ? parent.removeChild(elem);}},

? ? ? ? // url 組裝

? ? ? ? parseData: function(data){

? ? ? ? ? ? ? ? var ret = "";

? ? ? ? ? ? ? ? if( typeof data === "string" ){

? ? ? ? ? ? ? ? ? ? ? ? ret = data;}else if( typeof data === "object"){

? ? ? ? ? ? ? ? ? ? ? ? for(var key in data){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret += "&" + key + "=" +encodeURLComponent(data[key])

? ? ? ? ? ? ? ? }}

? ? ? ? ? ? ? ? // 加個時間錯,防止緩存

? ? ? ? ? ? ? ? ret += "&_time=" + this.now();

? ? ? ? ? ? ? ? ret +=ret.substr(1);

? ? ? ? ? ? ? ? return ret;},

? ? ? ? ? ? getJSON: function(url, data, func){

? ? ? ? ? ? ? ? ? ? ? ? ? ? var name; //函數(shù)名稱

? ? ? ? ? ? ? ? ? ? ? ? ? ? url = url + (url.indexOf("?") === -1? "?":"&" ) + this.paresData(data)

? ? ? ? ? ? ? ? ? ? ? ? ? ? // 檢查callback的函數(shù)名稱是否已經(jīng)定義

? ? ? ? ? ? ? ? ? ? ? ? ? ? var? match= /callback=(\w+)/.exec(url)

? ? ? ? ? ? ? ? ? ? ? ? ? ? if(match && match[1]){?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? name = match[1]}else{

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 如果未定義函數(shù)名的話,隨機生成一個函數(shù)名

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //隨機生成的函數(shù)名通過時間錯拼成16位隨機數(shù)的方式,重名的概率基本為0

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //? 如: jsonp_1355750852040_8260732076596469

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?name = "jsonp_" + this.now() + "_" + this.rand();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //把callback中的? 替換成函數(shù)名

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? url = url.replace("callback=?","callback="+name)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 處理?被encode的情況

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?url= url.replace('callback=%3F', "callback="+name)}

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 創(chuàng)建一個script元素

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? var script = document.createElement('script');

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? script.type = "text/javascript"

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? script.src = url;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? script.id = "id_" +name //設置id,為了后面可以刪除這個元素

? ?????????????????????????????? // 把傳進來的函數(shù)重新組裝,并把它設置為全局函數(shù),遠程就是調(diào)用這個函數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?window[name] = function(json){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? window[name] = undefined;?// 執(zhí)行這個函數(shù)后,要銷毀這個函數(shù)

? ???????????????????????????????????????????????????????????var elem = document.getElementById("id_" + name); // 獲取這個script的元素?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????????????????????????????????????????????????????JSONP.removeElem(elem); // // 刪除head里面插入的script,這三步都是為了不影響污染整個DOM? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? func(json); // 執(zhí)行傳入的函數(shù)}

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 在head里面插入script元素

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?var head = document.getElementsByTagName("head");

? ??????????????????????????????if(head && head[0]) {

????????????????????????????????????????????head[0].appendChild(script); }}}

調(diào)用

var data = { from: "北京", count: 27, output: "json", callback: "?" }

JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp", data, function(json) {console.log(json)});



原文鏈接:?https://www.cnblogs.com/naokr/p/6603936.html

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容