這是我在13年初寫的文章,當時懵懵懂懂寫下了本身對
JSONP
的理解。javascript文章原文前端
博客 歡迎訂閱java
提到JSONP,我當時在網上找了無數帖子也沒有看懂它。那些文章大同小異,都是講到JSONP原理之後就戛然而止,把咱們這些初學者搞得雲裏霧裏。因此,寫下這篇文章,但願對你們有幫助!git
回答這個問題以前,你們先想一想什麼是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
上的數據,行不行呢?答:不行!仍是由於」同源策略」!咱們想從本身信任的網頁上取得數據都不行,這可怎麼辦呢?網絡
在須要跨域通訊的歲月裏,一些卓越的前端工程師們想到了這個」做弊」的辦法來逃避」同源策略」。」同源策略」雖然很厲害,阻止了一個頁面到另外一個頁面的通訊,但是src
指向的路徑它放過了,提到src
,你們是否是想起了<script>
?對,JSONP就是利用」同源策略」的這一」漏洞」來進行」做弊」的。(其實有src
屬性的不止有<script>
,還有<img>
和<iframe>
,而<iframe>
也是可以運用JSONP
的)。
下面看看JSONP
的原理:
JSONP
:JSON with Padding
,JSON
你們這都知道,是一種數據通訊格式,而」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
這個詞很形象地形容了這個過程。
在網上能找到的JSON基本只是介紹到這裏就完了,可是這讓初學者看不到一個實實在在的例子。因此下面纔是這篇文章和其餘網上介紹JSON文章不同的地方,我帶給你們一個例子!
你們必定對百度的自動搜索框有印象,它就是一個JSONP的實例:
先查看demo
分析一下:
1.分析數據地址回顧上面的例子,咱們首先要知道數據的來源地址,就是上面的www.bbb.com/abc.js
裏的數據。在Chrome中查看Network。而後隨便在搜索框裏輸入點什麼,好比s
,觀察Network裏是否是多了東西,點開它,就是咱們輸入「s」後傳回的數據了:
這個地址是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函數:
這樣,咱們的數據就包在了succ函數裏作一個參數,再次證實了JSON with Padding 的原理。
2.作<script>
標籤,其src指向數據地址:這是要動態生成的,不能把地址寫死,要否則取到的都是同樣的數據了。因此咱們要動態生成<script>
,動態指定src
屬性:
var oScript = document.createElement('script'); oScript.src = 'http://suggestion.baidu.com/su?wd='+oTxt.value+'&p=3&cb=succ&from=superpage'; document.body.appendChild(oScript);
3.不要覺得這樣問題就解決了,F12一下,就看到生成了好多<script>
!這是由於咱們每輸入一個字符就動態生成一個<script>
,形成了代碼冗餘!解決一下:
if(oScript){ document.body.removeChild(oScript); }
好,這樣,咱們的搜索框效果就作好了,由於主要講JSONP部分的工做原理,就不作成百度下拉框那樣了,你們能夠本身去佈局。固然,真正的百度搜索框還要在此基礎上涉及事件的冒泡取消等等,就不是這裏的重點了,不作闡述。
JSONP是爲了傳數據而存在的技術。網頁之間的通訊本來有AJAX就夠了,而AJAX由於瀏覽器「同源策略」面對跨域狀況就一籌莫展了。JSONP就這樣被髮明瞭,利用<script>
的src
屬性不受「同源策略」的控制,「做弊」般地巧妙地逃過了瀏覽器的這一限制。
JSONP方法本質是建立<script>
標籤,其src
指向咱們的數據地址。地址後面附帶一個回調函數(名字通常是callback或者是別的什麼,就看後臺給咱們的是什麼了,函數名是咱們起的)。而後,聲明這個回調函數。這樣,只要一引入上面的<script>
標籤,就至關於執行了那個回調函數。
雖然jQuery把JSONP內置在了AJAX裏,可是咱們必定要清楚,AJAX和JSONP是徹底不同的,必定不要混淆!之後我會更新一篇介紹AJAX的文章的。
這裏是前端和後臺的交匯之處,想要真正融會貫通,還要學學後臺的知識。我也是在學了PHP以後才把JSONP搞懂的。