您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)如何進行JSONP跨域模擬百度搜索,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
JSONP
是JSON with padding
(填充式JSON或參數(shù)式JSON)的簡寫,是應(yīng)用JSON的一種新方法,在后來的Web服務(wù)中非常流行,JSONP看起來與JSON差不多,只不過是被包含在函數(shù)中調(diào)用的JSON,就像下面這樣:
callback({"name": "王歡"});
SONP由兩部分組成:回調(diào)函數(shù)和數(shù)據(jù)?;卣{(diào)函數(shù)是當(dāng)響應(yīng)到來時應(yīng)該在頁面 中調(diào)用的函數(shù)。回調(diào)函數(shù)的名字一般是在請求中指定的。而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù)。下面就是一個典型的JSONP請求。
https://freegeoip.net/json/?callback=handleResponse
這個URL是在請求一個JSONP
地理定位服務(wù),通過查詢字符串來指定JSONP服務(wù)的回調(diào)參數(shù)是很常見的,就像上面的URL所示,這里指定的回調(diào)函數(shù)的名字叫做:handleResponse()
JSONP是通過動態(tài)<script>
元素來使用的,使用時可以為src屬性指定一個跨域URL??梢圆皇芟拗频膹钠渌蚣虞d資源,因為JSONP是有效的JavaScript
代碼,所以在請求完成后,即在JSONP響應(yīng)加載到頁面中以后,就會立即執(zhí)行。
我們知道,同源策略是瀏覽器的一種安全機制,所謂的源是指協(xié)議、域名和端口號,當(dāng)我們的腳本在運行時,瀏覽器會檢測它所執(zhí)行的腳本和他所取得的的數(shù)據(jù)與我們HTML頁面是否相同,如果相同,就是同源的,會進行成功的請求,如果他們的源不相同,就是跨域請求。在默認(rèn)情況下,瀏覽器是不支持跨域請求的,那么如果我們想要跨域請求,該如何操作呢?
script
標(biāo)簽是不受同源策略的限制的,即我們在請求script腳本的時候,無論是在HTML所在的服務(wù)器還是其他服務(wù)器,它都可以請求到,所以我們就利用script
標(biāo)簽的這種性質(zhì)來進行數(shù)據(jù)的跨域請求。就來看看JSONP
是如何進行跨域請求的。
首先,我們請求一段script
代碼,這段代碼里如果它能調(diào)用我們所指定的一個函數(shù),并將數(shù)據(jù)作為實參傳遞進來,那么只要我們定義了這個函數(shù)并定義了形參,形參就會接收到他的實參來得到數(shù)據(jù)。舉個例子:
假設(shè)在腳本中定義了一個getData(data)
,如果現(xiàn)在請求一個腳本,這個腳本能夠調(diào)用getData()這個函數(shù),并將data 作為實參傳遞進來,那形參收到的數(shù)據(jù)就可以進行相應(yīng)的處理。
<script> function getData(data){ console.log(data); } var script = document.createElement('script'); script.id = 'jsonp'; script.src = 'jsonp.js'; document.body.appendChild(script); </script>
假設(shè)前端已經(jīng)把函數(shù)名告訴了后端,后端就可以調(diào)用這個getData()
,并且可以傳遞信息。在jsonp.html
就可以請求到下述jsonp.js
文件。
getData({ name: '小王', age: 20 })
運行得到結(jié)果為:
得到了一個Object
對象,就是我們所傳遞的數(shù)據(jù)。
那么,我們?nèi)绾胃嬖V服務(wù)器getData()
這個函數(shù)呢?如果我們每次都固定是getData(),
我們的開發(fā)會很死板,就不能定義其他函數(shù)名字。實際上,我們可以通過get請求將我們前端定義的函數(shù)名字通過參數(shù)告訴后端,后端動態(tài)生成這樣的一個腳本文件并返回給函數(shù)的調(diào)用就可以。
百度就有一個這樣的接口,我們一起來看看。
打開瀏覽器百度頁面,打開調(diào)試工具,看一下NETwork
標(biāo)簽下面會監(jiān)聽所有關(guān)于瀏覽器向服務(wù)器發(fā)送的http請求并查看數(shù)據(jù)。
在搜索框鍵入“b”,請求如圖:
請求得到的關(guān)鍵字為:
這里的callback
函數(shù)其實是jquery生成的一個全局函數(shù)。得到這個URL
后,我們可以保存其有用的信息,并將回調(diào)函數(shù)換成別的函數(shù):
https://www.baidu.com/sugrec?pre=1&wd=b&req=2&csor=1&cb=getData();
將其輸入到地址欄中進行測試:
可以發(fā)現(xiàn),這個回調(diào)函數(shù)就變成了我們設(shè)置的。
我們現(xiàn)在就可以通過這個接口去發(fā)生JSON來模擬一下百度搜索頁面。
我們定義一個全局變量作為接收數(shù)據(jù)的函數(shù),data就是接收到的數(shù)據(jù),一旦getdata()
函數(shù)被調(diào)用,說明我們我們的Jsonp函數(shù)就發(fā)送完成,此時可以通過removeChild()
刪除script標(biāo)簽,這樣就可以實現(xiàn)每當(dāng)我們發(fā)送一次請求,script
標(biāo)簽在接收到數(shù)據(jù)后就會被刪除,在數(shù)據(jù)處理的時候,getData()
返回給我們的是一個對象,對象里面有一個關(guān)鍵字g,里面對應(yīng)的是一個數(shù)組,數(shù)組里面是字符串,我們先將這個數(shù)組遍歷,然后根據(jù)每個元素生成一個li加到input下面的ul就可以,先將ul里面的html清空,這樣的話,每次請求的li都是全新的,當(dāng)keyup
出來的時候,首先取到當(dāng)前input
的value值并調(diào)用getdata()
函數(shù),將wd傳進來,就實現(xiàn)了jsonp傳遞數(shù)據(jù)的過程。
代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { position: relative; width: 600px; height: 40px; } input { width: 500px; height: 40px; border: 2px solid #4E6EF2; } button{ position: absolute; left: 411px; top: 0; width: 95px; height: 44px; background-color: #4E6EF2; border: none; font-size: 18px; color: white; } ul{ position: relative; left: -40px; top: -10px; width: 411px; height: 400px; } li{ height: 40px; width: 411px; line-height: 40px; font-size: 16px; list-style: none; } </style> </head> <body> <div> <input type="text" value =''> <button>百度一下</button> </div> <ul></ul> <script src="jquery.js"></script> <script> // function getData(data){ var script = document.querySelector('#jsonp'); script.parentNode.removeChild(script); $('ul').html(''); for(var i =0;i<data.g.length;i++){ $('<li>'+data.g[i].q +'</li>').appendTo('ul'); } } //動態(tài)生成script腳本 function getList(wd){ var script = document.createElement('script'); script.id = 'jsonp'; script.src = 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=26350&req=2&csor=1&cb=getData&wd='+wd; document.body.appendChild(script); } //給 var ipt = document.querySelector('input'); ipt.addEventListener('keyup',function(){ var wd = this.value; getList(wd); console.log(wd); }) </script> </body> </html>
效果為:
JSONP之所以在開發(fā)人員中極為流行,是因為它非常簡單易用,不過他也有兩點不足:
首先,JSONP
是從其他域中加載執(zhí)行代碼。如果其他域不安全,很可能會在響應(yīng)中夾帶一些惡意代碼,而此時除了完全放棄JSONP調(diào)用之外,沒有辦法追究。
其次,要確定JSONP請求是否失敗并不容易。雖然HTML5給
<script>元素新增了一個onerror事件處理程序,但目前還沒有得到任何瀏覽器的支持。為此,開發(fā)人員不得不使用計時器檢測指定時間內(nèi)是否接收到了響應(yīng)。但是畢竟不是每個用戶的上網(wǎng)速度和帶寬都一樣,所以操作起來也不盡人意。
關(guān)于如何進行JSONP跨域模擬百度搜索就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。