首頁 >web前端 >js教程 >說說JSON和JSONP 也許你會豁然開朗_json

說說JSON和JSONP 也許你會豁然開朗_json

WBOY
WBOY原創
2016-05-16 17:50:20894瀏覽

前言

  由於Sencha Touch 2這種開發模式的特性,基本上決定了它原生的資料互動行為幾乎只能透過AJAX來實現。

  當然了,透過呼叫強大的PhoneGap插件然後打包,你可以實現100%的Socket通訊和本地資料庫功能,又或者透過HTML5的WebSocket也可以實現與伺服器的通訊和服務端推功能,但這兩種方式都有其局限性,前者需要PhoneGap支持,後者要求使用者設備必須支援WebSocket,因此都不能算是ST2的原生解決方案,原生的只有AJAX。

  說到AJAX就會不可避免的面臨兩個問題,第一個是AJAX以何種格式來交換資料?第二個是跨域的需求如何解決?這兩個問題目前都有不同的解決方案,例如資料可以用自訂字串或用XML來描述,跨域可以透過伺服器端代理來解決。

  但到目前為止最被推崇或者說首選的方案還是用JSON來傳數據,靠JSONP來跨域。而這就是本文將要講述的內容。

  JSON(JavaScript Object Notation)和JSONP(JSON with Padding)雖然只有一個字母的差別,但其實他們根本不是一回事:JSON是一種資料交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域資料互動協定。我們拿最近比較火的諜戰片來打個比方,JSON是地下黨們用來書寫和交換情報的“暗號”,而JSONP則是把用暗號書寫的情報傳遞給自己同志時使用的接頭方式。看到沒?一個是描述訊息的格式,一個是訊息傳遞雙方約定的方法。

  既然隨便聊聊,那我們就不再採用教條的方式來講述,而是把關注重心放在幫助開發人員理解是否應當選擇使用以及如何使用上。

  什麼是JSON

  前面簡單說了一下,JSON是一種基於文本的資料交換方式,或者叫做資料描述格式,你是否該選用他首先一定要注意它所擁有的優點。

JSON的優點:

  1、基於純文本,跨平台傳遞極為簡單;

 1、基於純文本,跨平台傳遞極為簡單;

  2、台語言幾乎全部支援;

  3、輕量級資料格式,佔用字元數量極少,特別適合網路傳遞;

  4、可讀性較強,雖然比不上XML那麼一目了然,但在合理的依序縮排之後還是很容易辨識的;

  5、容易編寫和解析,當然前提是你要知道資料結構;

  JSON的缺點當然也有,但在作者看來實在是無關緊要的東西,所以不再單獨說明。
JSON的格式或叫規則:


  JSON能夠以非常簡單的方式來描述資料結構,XML能做的它都能做,因此在跨平台方面兩者完全不分伯仲。

  1、JSON只有兩種資料型別描述符,大括號{}和方括號[],其餘英文冒號:是映射符,英文逗號,是分隔符,英文雙引號""是定義符。

  2、大括號{}用來描述一組「不同類型的無序鍵值對集合」(每個鍵值對可以理解為OOP的屬性描述),方括號[]用來描述一組「相同類型的有序資料集合」(可對應OOP的陣列)。

  3、上述兩種集合中若有多個子項,則透過英文逗號,進行分隔。

  4、鍵值對以英文冒號:進行分隔,並且建議鍵名都加上英文雙引號”",以便於不同語言的解析。

  5、JSON內部常用資料類型無非就是字串、數字、布林、日期、null 這麼幾個,字串必須用雙引號引起來,其餘的都不用,日期類型比較特殊,這裡就不展開講述了,只是建議如果客戶端沒有按日期排序功能需求的話,那麼把日期時間直接作為字符串傳遞就好,可以省去很多麻煩。
  
JSON實例:

複製代碼
代碼如下:

// 描述一個人
var person = {
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
}
// 取得這個人的資訊
var personAge = person.Age;
// 描述幾個人
var members = [
{
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
},
{
"Name": "John",
"Age": 20,
"Company": "Oracle",
"Engineer": false
},
{
" Name": "Henry",
"Age": 45,
"Company": "Microsoft",
"Engineer": false
}
]
// 讀取其中John的公司名稱
var johnsCompany = members[1].Company;
// 描述一次會議
var conference = {
"Conference": "Future Marketing",
"Date ": "2012-6-1",
"Address": "Beijing",
"Members":
[
{
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
},
{
"Name": "John",
"Age ": 20,
"Company": "Oracle",
"Engineer": false
},
{
"Name": "Henry",
"Age": 45,
"Company": "Microsoft",
"Engineer": false
}
]
}
// 讀取參與者Henry是否工程師
var henryIsAnEngineer = conference.Members[2].Engineer;

關於JSON,就說這麼多,更多細節請在開發過程中查閱資料深入學習。

  什麼是JSONP

  先說說JSONP是怎麼產生的:

  其實網上關於JSONP的講解有很多,但卻千篇一律,而且雲裡霧裡,對於很多剛接觸的人來講理解起來有些困難,小可不才,試著用自己的方式來闡釋一下這個問題,看看是否有幫助。

  1、一個眾所周知的問題,Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一律不准;

  2、不過我們又發現,Web頁面上呼叫js檔案時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有」src」這個屬性的標籤都擁有跨域的能力,例如、說說JSON和JSONP 也許你會豁然開朗_json

  3、於是可以判斷,當前階段如果想透過純web端(ActiveX控制項、服務端代理、屬於未來的HTML5之Websocket等方式不算)跨域存取資料就只有一種可能,那就是在遠端伺服器上設法把資料裝進js格式的檔案裡,供客戶端呼叫和進一步處理;

  4、恰巧我們已經知道有一種叫做JSON的純字符數據格式可以簡潔的描述複雜數據,更妙的是JSON還被js原生支持,所以在客戶端幾乎可以隨心所欲的處理這種格式的數據;

  5、這樣子解決方案就呼之欲出了,web客戶端透過與調用腳本一模一樣的方式,來調用跨域伺服器上動態生成的js格式檔案(一般以JSON為後綴),顯而易見,伺服器之所以要動態產生JSON文件,目的就在於把客戶端需要的資料裝進去。

  6、客戶端在對JSON檔案呼叫成功之後,也就獲得了自己所需的數據,剩下的就是按照自己需求進行處理和展現了,這種獲取遠端數據的方式看起來非常像AJAX ,但其實不一樣。

  7、為了便於客戶端使用數據,逐漸形成了一種非正式傳輸協議,人們把它稱作JSONP,該協議的一個要點就是允許用戶傳遞一個callback參數給服務端,然後服務端返回數據時會將這個callback參數當作函數名稱來包裹住JSON數據,這樣客戶端就可以隨意自訂自己的函數來自動處理回傳資料了。

  如果對於callback參數如何使用還有些模糊的話,我們後面會有具體的實例來講解。

  JSONP的客戶端具體實作:

  不管jQuery也好,ExtJs也罷,又或者是其他支援jsonp的框架,他們幕後所做的工作都是一樣的,下面我來循序漸進的說明一下jsonp在客戶端的實現:

  1、我們知道,就算跨域js檔案中的程式碼(當然指符合web腳本安全策略的),web頁面也是可以無條件執行的。

  遠程服務器remoteserver.com根目錄下有個remote.js文件代碼如下:

複製代碼 代碼如下:

alert('我是遠端檔案');  

本地伺服器localserver.com下有個jsonp.html頁面程式碼如下:
複製程式碼 程式碼如下:











毫無疑問,頁面將會彈出一個提示窗體,顯示跨域呼叫成功。

  2、現在我們在jsonp.html頁面定義一個函數,然後在遠端remote.js中傳入資料進行呼叫。

  jsonp.html頁碼如下:
複製程式碼



複製程式碼



複製碼>






複製程式碼


複製程式碼



複製程式碼複製程式碼
>

程式碼如下:


localHandler({"result":"我是遠端js帶來的資料"});


運作之後查看結果,頁面成功彈出提示窗口,顯示本地函數被跨域的遠端js呼叫成功,也接收了遠端js帶來的資料。很欣喜,跨域遠端取得資料的目的基本上實作了,但是又一個問題出現了,我要怎麼讓遠端js知道它應該呼叫的本地函數叫什麼名字呢?畢竟是jsonp的服務者都要面對許多服務對象,而這些服務對象各自的本地函數都不相同啊?我們接著往下看。

  3、聰明的開發者很容易想到,只要服務端提供的js腳本是動態生成的就行了唄,這樣呼叫者可以傳一個參數過去告訴服務端「我想要一段呼叫XXX函數的js程式碼,請你回傳給我”,於是伺服器就可以按照客戶端的需求來產生js腳本並回應了。

  看jsonp.html頁面的程式碼:




複製程式碼



複製程式碼
程式碼:
這次的程式碼變化比較大,不再直接把遠端js檔案寫死,而是編碼實作動態查詢,而這也正是jsonp客戶端實現的核心部分,本例中的重點也就在於如何完成jsonp調用的全過程。

  我們看到調用的url中傳遞了一個code參數,告訴服務器我要查的是CA1998次航班的信息,而callback參數則告訴服務器,我的本地回調函數叫做flightHandler,所以請把查詢結果傳入這個函數中進行呼叫。

  OK,伺服器很聰明,這個叫做flightResult.aspx的頁面產生了一段這樣的程式碼提供給jsonp.html(服務端的實作這裡就不示範了,與你選用的語言無關,說到底就是拼接字串):
複製程式碼 程式碼如下:

flightHandler({{
" code": "CA1998",
"price": 1780,
"tickets": 5
});  

我們看到,傳遞給flightHandler json,它描述了航班的基本資訊。運行一下頁面,成功彈出提示窗口,jsonp的執行全過程順利完成!

  4、到這裡為止的話,相信你已經能夠理解jsonp的客戶端實現原理了吧?剩下的就是如何把程式碼封裝一下,以便於與使用者介面交互,從而實現多次和重複呼叫。

  什麼?你用的是jQuery,想知道jQuery如何實作jsonp呼叫?好吧,那我就好人做到底,再給你一段jQuery使用jsonp的代碼(我們依然沿用上面那個航班信息查詢的例子,假定返回jsonp結果不變):
複製代碼 代碼如下:




Untitled Page





陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn