封装-Jsonp
封裝-Jsonp
- Jsonp
- jsonp是什么?
- 為什么使用jsonp?
- 原理---jsonp的通俗講解
- 案例---使用script的src獲取跨域數(shù)據(jù)
- 封裝Jsonp
- 案例---獲取qq.com中的城市信息與天氣信息
Jsonp
jsonp是什么?
- 通過script標(biāo)簽中的src屬性沒有同源限制的方法進(jìn)行獲取數(shù)據(jù)
即通過script標(biāo)簽來跨域獲取數(shù)據(jù),名為JSON with Padding,
或者就叫JSONP。JSONP的原理很簡單,但需要服務(wù)器端給予相應(yīng)配合。
大致來說,JSONP的實現(xiàn)思路就是在客戶端編程時作好使用JSON數(shù)據(jù)的準(zhǔn)備,然后再通過圓括號將這些數(shù)據(jù)括起來以創(chuàng)建一條有效的JavaScript語句(可能是一次有效的函數(shù)調(diào)用)。
也就是說,客戶端可以使用一個用于命名jsonp的查詢參數(shù)來決定可以獲取的數(shù)據(jù)。最簡單的情況下,如果jsonp參數(shù)為空,則返回的數(shù)據(jù)就是被括在圓括號中的JSON
為什么使用jsonp?
瀏覽器安全模型規(guī)定,XMLHttpRequest、框架(frame)等只能在一個域中通信。
從安全角度考慮,這個規(guī)定很合理;
但是,也確實給分布式(面向服務(wù)、混搭等等本周提到的概念)Web開發(fā)帶來了麻煩。
-
本地代理:
需要一些硬件設(shè)施(沒有服務(wù)器的客戶端無法運(yùn)行),并且?guī)捄蜐摲鼤r間也要加倍(遠(yuǎn)程服務(wù)器-代理服務(wù)器-客戶端)。 -
Flash:
遠(yuǎn)程主機(jī)中需要部署一個crossdomain.xml文件,而且,Flash作為一門專有技術(shù),其前途尚不明朗;換句話說,開發(fā)人員很可能要學(xué)習(xí)一種目標(biāo)不確定的編程語言。 -
Script標(biāo)簽:
無法確切知道內(nèi)容是否有效,沒有標(biāo)準(zhǔn)的實現(xiàn)方法,又可能被認(rèn)為是一種“安全風(fēng)險”。
原理—jsonp的通俗講解
- 使用script 的src屬性沒有同源限制,跨域名獲取數(shù)據(jù)的一種方法
案例—使用script的src獲取跨域數(shù)據(jù)
<script type="text/javascript">// 定義一個jp函數(shù)function jp(data) {console.log(data);} </script> <!-- 使用script 的src屬性沒有同源限制,跨域名獲取數(shù)據(jù)的一種方法 --><!-- 獲取qq.com的天氣信息,callback是返回的數(shù)據(jù),jp是返回數(shù)據(jù)后調(diào)用的方法 --> <script src="https://apis.map.qq.com/ws/location/v1/ip?callback=jp&key=CAABZ-AVSAQ-RDR5L-GTBDJ-HLA4O-A5FDB&output=jsonp" ></script>封裝Jsonp
- 原理:
- 使用script 的src屬性沒有同源限制,跨域名獲取數(shù)據(jù)的一種方法
- 動態(tài)的創(chuàng)建script標(biāo)簽,使用src屬性來進(jìn)行跨域獲取數(shù)據(jù)
- 其中使用有Promise,異步
案例—獲取qq.com中的城市信息與天氣信息
<!DOCTYPE html> <html><head><meta charset="utf-8"><title></title></head><body><p id="city" ></p><img src="" id="img" alt=""><p id="weather"></p></body><script type="text/javascript">// jsonp 利用script的src屬性沒有同源限制,跨域名獲取數(shù)據(jù)的一種方法// 后端返回的數(shù)據(jù)格式是,方法名(數(shù)據(jù))// url 最重要 callback名稱 jp 是callback的值function jsonp(url,option={}) {// 默認(rèn)回調(diào)函數(shù)參數(shù)名 callbackvar jp = option.jp||"callback"; // 默認(rèn)回調(diào)函數(shù)參數(shù)值var callback = option.callback||"jp";return new Promise((resolve,reject) => {// 查看url是否有jp 沒有還要加上if(url.indexOf(jp)==-1){url += "&"+jp+"="+callback;}// 如果有獲取這已經(jīng)加上了callback=值,獲取callback的值var p1 = url.indexOf(jp); // 獲取到callback的位置var p2 = url.indexOf("&",p1); // 從p1的位置開始查找符號"&"// 如果查找不到設(shè)置的p2位置,p2 == -1 ? p2 = url.lenght : '';// 就在url的末尾加,callback = url.slice(p1+jp.length+1,p2);// 動態(tài)的創(chuàng)建callback方法window[callback]=function(data){ // 刪除document.head.removeChild(script);resolve(data); }// 動態(tài)創(chuàng)建script標(biāo)簽let script = document.createElement("script");// 將需要獲取的數(shù)據(jù)的地址賦值給script 中的src屬性,跳過瀏覽器的同源策略script.src = url;// 將script標(biāo)簽追加到head中document.head.append(script); // script加載失敗script.onerror = function(e){// 動態(tài)刪除scriptdocument.head.removeChild(script); reject(e)}})}var url1 = "https://apis.map.qq.com/ws/location/v1/ip?key=CAABZ-AVSAQ-RDR5L-GTBDJ-HLA4O-A5FDB&output=jsonp";var url2 = "https://wis.qq.com/weather/common?weather_type=observe|forecast_24h|air&source=pc&callback=jp";// 獲取地址jsonp(url1).then(res=>{url2 = url2+`&province=${res.result.ad_info.province}&city=${res.result.ad_info.city}`;city.innerHTML=res.result.ad_info.city;return jsonp(url2); //獲取天氣}).then(res=>{weather.innerHTML=res.data.observe.degree+"℃";// 動態(tài)的天氣圖片img.src="https://mat1.gtimg.com/pingjs/ext2020/qqindex2018/dist/img/weather/"+res.data.observe.weather_code+".svg";})</script> </html>總結(jié)
- 上一篇: x58和x79服务器性能,X58接班人:
- 下一篇: 电脑无线网卡连接的无线信号不好的,经常丢