用原生JS封裝一個簡單的JSONP,主要是用來理解前端是怎么實作JSONP的,
JSONP跨域是借助<img><script>的src屬性,<link>的href屬性能夠鏈接外部網站,來實作跨域請求資料,
將跨域請求的鏈接和引數以鏈接的方式提交給服務器,同時在鏈接中附帶本地接收JSONP資料函式的函式名,當服務器查找資料完畢后,呼叫該函式,并將資料以函式引數形式傳出,
首先,使用使用JSONP跨域,不是直接回傳一個資料物件,而是本地向服務器提供一個可供呼叫的函式fn,由服務器呼叫,并跨域請求的資料物件注入fn的引數,也就是說,跨域請求資料,是將本地用來接受JSONP資料物件的函式的函式名提交給服務器,由服務器來呼叫,
其次,因為網頁中會頻繁使用到JSONP,本地用來接收JSONP資料的函式將會有很多,從而導致代碼冗余,占用資源,
因此,采取以下方法接收JSONP跨域請求得到的資料:
1、在封裝函式Fun中隨機生成一個變數名fn;
2、將fn保存為封裝函式Fun的屬性(即:Fun[fn]),或者window的全域屬性;
3、將fn提交給服務器做為本地接收JSONP函式的函式名;
4、定義本地接收JSONP資料的匿名函式,并將匿名函式賦值給封裝函式Fun的屬性fn(Fun[fn] = function(data){...});
5、將匿名函式中接收到的data傳出,或在匿名函式中呼叫封裝函式傳入的回呼函式(如果有的話);
6、洗掉Fun[fn]屬性,也就是銷毀接收函式,
這樣,既解決本地用來接收JSONP是提供的回呼函式容易重名,又在每次執行完成后銷毀回呼函式減少代碼冗余,
1 <script> 2 /* 3 * 封裝JSONP 4 * url: 跨域地址 5 * callback:處理資料的回呼函式 6 */ 7 function getJSONP(url, callback) { 8 if (!url) { // url為空,則退出 9 return; 10 } 11 12 // 隨機生成工具函式的函式名 13 var fnName = '_JSONP'+ parseInt(Math.random()*100); 14 // 將這個沒有賦值的函式名變成getJSONP的屬性,因為函式名是以字串形式提交,因此此處更改之后url中提交的形式為cb=getJSONP._JSONPXX,XX為兩個隨機生成的數字
15 var jsonp_attr = 'getJSONP.' + fnName; 16 17 // 判斷url地址中是否含有'?' 18 // 百度服務器JSONP回呼函式key屬性是'cb',為配合下邊鏈接,這里用'cb=',實際情況根據服務器提供的介面更改 19 if (url.indexOf('?') === -1) { 20 url += '?cb=' + jsonp_attr; 21 } 22 else{ 23 url += '&cb=' + jsonp_attr; 24 } 25 26 27 28 // 動態創建script標簽 29 var script = document.createElement('script'); 30 // 為script標簽src屬性賦值 31 script.src =https://www.cnblogs.com/walker-cheng/p/ url; 32 33 // 定義工具函式,并將工具函式賦給getJSONP的屬性fnName 34 getJSONP[fnName] = function (data) { 35 try { 36 // 跨域成功,通過回呼函式,處理資料 37 callback && callback(data); 38 } catch (error) { 39 // 40 } 41 finally{ 42 // 資料處理完成后,洗掉工具函式,以及實作跨域用的動態生成的script標簽 43 delete getJSONP[fnName]; 44 script.parentNode.removeChild(script); 45 } 46 } 47 48 49 // 將動態生成的script標簽添加到DOM,這一步發出跨域請求 50 document.getElementsByTagName('head')[0].appendChild(script); 51 } 52 53 // 使用封裝好的getJSONP函式 54 // 獲取在百度搜索欄輸入"iPhone"時,自動完成功能回傳的資料,注意將原來鏈接中回呼洗掉 55 getJSONP('https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=1436,31325,21091,31424,31341,31464,30824,31164&wd=iPhone&req=2&csor=6&pwd=iph&_=1588427887099', function (data) { 56 console.log(data); 57 }); 58 </script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/102423.html
標籤:JavaScript
上一篇:Vue使用rem做自適應布局
