淺談JSONP

這是我在13年初寫的文章,當時懵懵懂懂寫下了本身對JSONP的理解。javascript

文章原文前端

博客 歡迎訂閱java


提到JSONP,我當時在網上找了無數帖子也沒有看懂它。那些文章大同小異,都是講到JSONP原理之後就戛然而止,把咱們這些初學者搞得雲裏霧裏。因此,寫下這篇文章,但願對你們有幫助!git

爲何要有JSONP

回答這個問題以前,你們先想一想什麼是AJAX,JSONP就是一種可以解決AJAX辦不到的事情而存在的一種取數據的技術。什麼事情是AJAX辦不到的呢?就是跨域!github

跨域:顧名思義,就是當前網頁的地址和咱們要取的數據地址不在一個域下。這是由於瀏覽器都有一個「同源策略」— 兩個頁面的域名必須在同域的狀況下,才能容許通訊。json

怎麼纔算一個域呢?跨域

相同域名,相同端口,相同協議(由於不是這裏的重點,你們能夠請教Google)瀏覽器

「同源策略」的意義:「同源策略」有效地阻止了一些危險行爲,好比你進入www.aaa.com,同時瀏覽器又開了一個www.bbb.com,若是這個www.bbb.com是一個木馬網站,在沒有「同源策略」的狀況下,它就可能嵌入一些代碼,來取得你在www.aaa.com的信息(由於這時兩個頁面是能夠通訊的) 。而正是由於有了「同源策略」,剛纔能夠通訊的狀況纔不會發生。安全

「同源策略」帶來的麻煩:上面的例子是咱們在不知情的狀況下,保護咱們的網絡安全的,但若是咱們就是要讓www.aaa.com取得www.bbb.com上的數據,行不行呢?答:不行!仍是由於」同源策略」!咱們想從本身信任的網頁上取得數據都不行,這可怎麼辦呢?網絡

JSONP出現

在須要跨域通訊的歲月裏,一些卓越的前端工程師們想到了這個」做弊」的辦法來逃避」同源策略」。」同源策略」雖然很厲害,阻止了一個頁面到另外一個頁面的通訊,但是src指向的路徑它放過了,提到src,你們是否是想起了<script>?對,JSONP就是利用」同源策略」的這一」漏洞」來進行」做弊」的。(其實有src屬性的不止有<script>,還有<img><iframe>,而<iframe>也是可以運用JSONP的)。

下面看看JSONP的原理:

JSONP:JSON with PaddingJSON你們這都知道,是一種數據通訊格式,而」Padding」是什麼意思,別急,往下看就知道了。

咱們先舉一個簡單的例子:

www.aaa.com中:

<script type="text/javascript" src="http://www.bbb.com/abc.js"></script>
<script type="text/javascript">
    function abc(json){
        alert(json['name']); 
    }
</script>

www.bbb.com/abc.js中:

abc({'name':'risker','age':24});

頁面會彈出risker,有感受了麼?

JSONP是這樣工做的:像前面所說的那樣,咱們能夠取到www.bbb.com/abc.js,裏面是一個abc函數,這個函數也會被加載到www.aaa.com。加載完成後,就應該執行abc了,而後咱們在www.aaa.com定義abc函數,這個函數裏寫一些處理數據的語句。這樣其實就簡單地實現了跨域訪問數據了,這也就是JSONP的原理了。而JSON with Padding的意思,就是abc(json)中的json
abc({'name':'risker','age':24})

這個JSON對象被包在abc這個函數中看成參數來被處理,而JSON with Padding這個詞很形象地形容了這個過程。

JSONP的簡單實例

在網上能找到的JSON基本只是介紹到這裏就完了,可是這讓初學者看不到一個實實在在的例子。因此下面纔是這篇文章和其餘網上介紹JSON文章不同的地方,我帶給你們一個例子!
你們必定對百度的自動搜索框有印象,它就是一個JSONP的實例:

62504685.jpg

先查看demo

分析一下:

1.分析數據地址回顧上面的例子,咱們首先要知道數據的來源地址,就是上面的www.bbb.com/abc.js裏的數據。在Chrome中查看Network。而後隨便在搜索框裏輸入點什麼,好比s,觀察Network裏是否是多了東西,點開它,就是咱們輸入「s」後傳回的數據了:

82372497.jpg

這個地址是http://suggestion.baidu.com/su?wd=S&p=3&cb=window.bdsug.sug&from=superpage&t=1365392859833 , 咱們分析一下,wd後面是s,那就能夠判定百度定義wd是搜索的關鍵字,cb是一個回調函數,其餘的對咱們就不重要了。回調函數是咱們取到數據要後執行的函數,至關於咱們上面的abc函數。它是能夠本身取名的。像http://suggestion.baidu.com/su?wd=S&p=3&cb=succ&from=superpage表示取到數據後執行succ函數:

28602969.jpg

這樣,咱們的數據就包在了succ函數裏作一個參數,再次證實了JSON with Padding 的原理。

2.作<script>標籤,其src指向數據地址:這是要動態生成的,不能把地址寫死,要否則取到的都是同樣的數據了。因此咱們要動態生成<script>,動態指定src屬性:

var oScript = document.createElement('script');
oScript.src = 'http://suggestion.baidu.com/su?wd='+oTxt.value+'&amp;p=3&amp;cb=succ&amp;from=superpage';
document.body.appendChild(oScript);

3.不要覺得這樣問題就解決了,F12一下,就看到生成了好多<script>!這是由於咱們每輸入一個字符就動態生成一個<script>,形成了代碼冗餘!解決一下:

if(oScript){
document.body.removeChild(oScript);
}

好,這樣,咱們的搜索框效果就作好了,由於主要講JSONP部分的工做原理,就不作成百度下拉框那樣了,你們能夠本身去佈局。固然,真正的百度搜索框還要在此基礎上涉及事件的冒泡取消等等,就不是這裏的重點了,不作闡述。

JSONP總結

  1. JSONP是爲了傳數據而存在的技術。網頁之間的通訊本來有AJAX就夠了,而AJAX由於瀏覽器「同源策略」面對跨域狀況就一籌莫展了。JSONP就這樣被髮明瞭,利用<script>src屬性不受「同源策略」的控制,「做弊」般地巧妙地逃過了瀏覽器的這一限制。

  2. JSONP方法本質是建立<script>標籤,其src指向咱們的數據地址。地址後面附帶一個回調函數(名字通常是callback或者是別的什麼,就看後臺給咱們的是什麼了,函數名是咱們起的)。而後,聲明這個回調函數。這樣,只要一引入上面的<script>標籤,就至關於執行了那個回調函數。

  3. 雖然jQuery把JSONP內置在了AJAX裏,可是咱們必定要清楚,AJAX和JSONP是徹底不同的,必定不要混淆!之後我會更新一篇介紹AJAX的文章的。

  4. 這裏是前端和後臺的交匯之處,想要真正融會貫通,還要學學後臺的知識。我也是在學了PHP以後才把JSONP搞懂的。

相關文章
相關標籤/搜索