天天看點

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  第一次聽說jsonp,其實早在2年之前。當時在做一個活動頁面的抽獎子產品,要從服務端get一個機率,當時什麼都不懂,同僚說用ajax,我就用ajax,同僚說dataType改成jsonp,我就改成jsonp。于是乎活動頁面做完了,以後也沒有碰到過jsonp,在這期間我一直以為jsonp跟ajax息息相關,是xhr的一種特殊的跨域形式...直到一個月前的一次面試,問到jsonp我被虐成狗,才決定看下jsonp,好吧,原來jsonp也不是很難。

  相信大家對跨域一定不陌生,對同源政策也同樣熟悉。什麼,你沒聽過?沒關系,既然是深入淺出,那就從頭說起。

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  樓主把兩個檔案都放在wamp下的www檔案夾下,ajax請求沒有跨域,完美得到結果:

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  很顯然,提示跨域了!怎麼搞?這時jsonp就要出馬了!

  與jsonp息息相關的是script标簽,而xhr或者說傳統意義上的ajax與之沒有半毛錢關系!

  接着看上面的index.html代碼,我們看到頁面引用了百度cdn的jquery路徑,對于這樣的方式我們似乎已經習以為常,但是仔細一想,script标簽可是完完全全的跨域的啊...沒錯,jsonp的實作核心就是利用script标簽的跨域能力!于是我們靈機一動,似乎可以這麼搞,動态生成一個script标簽,把json的url指派給script的src屬性,然後再把這個script标簽插入dom裡...

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  我們建立了一個script标簽,而标簽内包裹的内容正是需要的json資料,但是報錯如下:

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  原因是因為json資料并不是合法的js語句,把上面的json資料放在一個回調函數中是最簡單的方法:

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  當然,這時的a.json檔案并不一定要這樣命名,改成a.js也不會有一點問題。

  而如果是與服務端互動也是一樣的道理,比如和php:

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  需要注意的是,jsonp提供的url(即動态生成的script标簽的src),無論看上去是什麼形式,最終生成傳回的都是一段js代碼。

  為了便于開發,jq對jsonp也進行了封裝,封裝在了ajax方法中。

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  以上代碼是針對請求檔案中寫死了callback函數名的情況。因為請求的是json檔案,json不是伺服器端的動态語言不能進行解析,如果是php或者其他的伺服器端語言,則不用寫死函數名,比如下面這樣:

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

當然類似的封裝好的方法還有幾種:

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結
深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  需要注意的是getJSON方法的請求位址url需要帶上callback=?,因為jq對該方法進行封裝的時候并沒有預設回調函數變量名為callback,于是php中$_GET['callback']就找不到變量值了。

  而一般的jq方法url 中不用指定 callback 參數。對于 jQuery 中的 jsonp 來說,callback 參數是自動添加的。預設情況下,jQuery 生成的 jsonp 請求中 callback 參數是形如 callback=jQuery200023559735575690866_1434954892929 這種根據看似随機的名字,對應的就是 success 那個處理函數,是以一般不用特意處理。二如果要寫死callback名的話,可以參照上文。

深入淺出jsonp(轉)前言為什麼要用jsonp?神奇的script标簽JQuery對jsonp的封裝總結

  由于同源政策的限制,XmlHttpRequest隻允許請求目前源(域名、協定、端口)的資源,為了實作跨域請求,可以通過script标簽實作跨域請求,然後在服務端輸出JSON資料并執行回調函數,進而解決了跨域的資料請求,這就是jsonp的核心。

  jsonp原理:

首先在用戶端注冊一個callback, 然後把callback的名字傳給伺服器。

伺服器先生成 json 資料。 然後以 javascript 文法的方式,生成一個function , function 名字就是傳遞上來的參數 jsonp. 最後将 json 資料直接以入參的方式,放置到 function 中,這樣就生成了一段 js 文法的文檔,傳回給用戶端。

用戶端浏覽器,解析script标簽,并執行傳回的 javascript 文檔,此時資料作為參數,傳入到了用戶端預先定義好的 callback 函數裡.(動态執行回調函數)

http://www.cnblogs.com/zichi/p/4593047.html