国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ajax 和jsonp 不是一碼事 細讀詳解

objc94 / 2515人閱讀

摘要:只有兩種數(shù)據(jù)類型描述符,大括號和方括號,其余英文冒號是映射符,英文逗號是分隔符,英文雙引號是定義符。上述兩種集合中若有多個子項,則通過英文逗號進行分隔。鍵值對以英文冒號進行分隔,并且建議鍵名都加上英文雙引號,以便于不同語言的解析。

由于Sencha Touch 2這種開發(fā)模式的特性,基本決定了它原生的數(shù)據(jù)交互行為幾乎只能通過AJAX來實現(xiàn)。
當然了,通過調用強大的PhoneGap插件然后打包,你可以實現(xiàn)100%的Socket通訊和本地數(shù)據(jù)庫功能,又或者通過HTML5的WebSocket也可以實現(xiàn)與服務器的通訊和服務端推功能,但這兩種方式都有其局限性,前者需要PhoneGap支持,后者要求用戶設備必須支持WebSocket,因此都不能算是ST2的原生解決方案,原生的只有AJAX。

說到AJAX就會不可避免的面臨兩個問題,第一個是AJAX以何種格式來交換數(shù)據(jù)?第二個是跨域的需求如何解決?這兩個問題目前都有不同的解決方案,比如數(shù)據(jù)可以用自定義字符串或者用XML來描述,跨域可以通過服務器端代理來解決。
但到目前為止最被推崇或者說首選的方案還是用JSON來傳數(shù)據(jù),靠JSONP來跨域。而這就是本文將要講述的內容。

JSON和JSONP雖然只有一個字母的差別,但其實他們根本不是一回事兒:JSON是一種數(shù)據(jù)交換格式,而JSONP是一種依靠開發(fā)人員的聰明才智創(chuàng)造出的一種非官方跨域數(shù)據(jù)交互協(xié)議。我們拿最近比較火的諜戰(zhàn)片來打個比方,JSON是地下黨們用來書寫和交換情報的“暗號”,而JSONP則是把用暗號書寫的情報傳遞給自己同志時使用的接頭方式??吹?jīng)]?一個是描述信息的格式,一個是信息傳遞雙方約定的方法。

既然隨便聊聊,那我們就不再采用教條的方式來講述,而是把關注重心放在幫助開發(fā)人員理解是否應當選擇使用以及如何使用上。
小小的廣告一下,該篇文章是在自己群里與Sencha Touch 2的開發(fā)者們一起探討ST2數(shù)據(jù)交互模型時有感而發(fā)寫出來的,因此如果您對Mobile Web App開發(fā)有興趣的話,歡迎加入Sencha Touch 交流 QQ 群 213119459 。

什么是JSON?

前面簡單說了一下,JSON是一種基于文本的數(shù)據(jù)交換方式,或者叫做數(shù)據(jù)描述格式,你是否該選用他首先肯定要關注它所擁有的優(yōu)點。

JSON的優(yōu)點:
1、基于純文本,跨平臺傳遞極其簡單;
2、JavaScript原生支持,后臺語言幾乎全部支持;
3、輕量級數(shù)據(jù)格式,占用字符數(shù)量極少,特別適合互聯(lián)網(wǎng)傳遞;
4、可讀性較強,雖然比不上XML那么一目了然,但在合理的依次縮進之后還是很容易識別的;
5、容易編寫和解析,當然前提是你要知道數(shù)據(jù)結構;
JSON的缺點當然也有,但在作者看來實在是無關緊要的東西,所以不再多帶帶說明。

JSON的格式或者叫規(guī)則:
JSON能夠以非常簡單的方式來描述數(shù)據(jù)結構,XML能做的它都能做,因此在跨平臺方面兩者完全不分伯仲。
1、JSON只有兩種數(shù)據(jù)類型描述符,大括號{}和方括號[],其余英文冒號:是映射符,英文逗號,是分隔符,英文雙引號""是定義符。
2、大括號{}用來描述一組“不同類型的無序鍵值對集合”(每個鍵值對可以理解為OOP的屬性描述),方括號[]用來描述一組“相同類型的有序數(shù)據(jù)集合”(可對應OOP的數(shù)組)。
3、上述兩種集合中若有多個子項,則通過英文逗號,進行分隔。
4、鍵值對以英文冒號:進行分隔,并且建議鍵名都加上英文雙引號"",以便于不同語言的解析。
5、JSON內部常用數(shù)據(jù)類型無非就是字符串、數(shù)字、布爾、日期、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,就說這么多,更多細節(jié)請在開發(fā)過程中查閱資料深入學習。

什么是JSONP?

先說說JSONP是怎么產(chǎn)生的:
其實網(wǎng)上關于JSONP的講解有很多,但卻千篇一律,而且云里霧里,對于很多剛接觸的人來講理解起來有些困難,小可不才,試著用自己的方式來闡釋一下這個問題,看看是否有幫助。
1、一個眾所周知的問題,Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態(tài)頁面、動態(tài)網(wǎng)頁、web服務、WCF,只要是跨域請求,一律不準;
2、不過我們又發(fā)現(xiàn),Web頁面上調用js文件時則不受是否跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有"src"這個屬性的標簽都擁有跨域的能力,比如




復制代碼
毫無疑問,頁面將會彈出一個提示窗體,顯示跨域調用成功。

2、現(xiàn)在我們在jsonp.html頁面定義一個函數(shù),然后在遠程remote.js中傳入數(shù)據(jù)進行調用。
jsonp.html頁面代碼如下:
復制代碼

var localHandler = function(data){ alert("我是本地函數(shù),可以被跨域的remote.js文件調用,遠程js帶來的數(shù)據(jù)是:" + data.result); };




復制代碼
remote.js文件代碼如下:
localHandler({"result":"我是遠程js帶來的數(shù)據(jù)"});
運行之后查看結果,頁面成功彈出提示窗口,顯示本地函數(shù)被跨域的遠程js調用成功,并且還接收到了遠程js帶來的數(shù)據(jù)。很欣喜,跨域遠程獲取數(shù)據(jù)的目的基本實現(xiàn)了,但是又一個問題出現(xiàn)了,我怎么讓遠程js知道它應該調用的本地函數(shù)叫什么名字呢?畢竟是jsonp的服務者都要面對很多服務對象,而這些服務對象各自的本地函數(shù)都不相同?。课覀兘又驴?。

3、聰明的開發(fā)者很容易想到,只要服務端提供的js腳本是動態(tài)生成的就行了唄,這樣調用者可以傳一個參數(shù)過去告訴服務端“我想要一段調用XXX函數(shù)的js代碼,請你返回給我”,于是服務器就可以按照客戶端的需求來生成js腳本并響應了。
看jsonp.html頁面的代碼:
復制代碼

// 得到航班信息查詢結果后的回調函數(shù) var flightHandler = function(data){ alert("你查詢的航班結果是:票價 " + data.price + " 元," + "余票 " + data.tickets + " 張。"); }; // 提供jsonp服務的url地址(不管是什么類型的地址,最終生成的返回值都是一段javascript代碼) var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 創(chuàng)建script標簽,設置其屬性 var script = document.createElement("script"); script.setAttribute("src", url); // 把script標簽加入head,此時調用開始 document.getElementsByTagName("head")[0].appendChild(script);




復制代碼
這次的代碼變化比較大,不再直接把遠程js文件寫死,而是編碼實現(xiàn)動態(tài)查詢,而這也正是jsonp客戶端實現(xiàn)的核心部分,本例中的重點也就在于如何完成jsonp調用的全過程。
我們看到調用的url中傳遞了一個code參數(shù),告訴服務器我要查的是CA1998次航班的信息,而callback參數(shù)則告訴服務器,我的本地回調函數(shù)叫做flightHandler,所以請把查詢結果傳入這個函數(shù)中進行調用。
OK,服務器很聰明,這個叫做flightResult.aspx的頁面生成了一段這樣的代碼提供給jsonp.html(服務端的實現(xiàn)這里就不演示了,與你選用的語言無關,說到底就是拼接字符串):
flightHandler({

"code": "CA1998",
"price": 1780,
"tickets": 5

});
我們看到,傳遞給flightHandler函數(shù)的是一個json,它描述了航班的基本信息。運行一下頁面,成功彈出提示窗口,jsonp的執(zhí)行全過程順利完成!

4、到這里為止的話,相信你已經(jīng)能夠理解jsonp的客戶端實現(xiàn)原理了吧?剩下的就是如何把代碼封裝一下,以便于與用戶界面交互,從而實現(xiàn)多次和重復調用。
什么?你用的是jQuery,想知道jQuery如何實現(xiàn)jsonp調用?好吧,那我就好人做到底,再給你一段jQuery使用jsonp的代碼(我們依然沿用上面那個航班信息查詢的例子,假定返回jsonp結果不變):
復制代碼




復制代碼
是不是有點奇怪?為什么我這次沒有寫flightHandler這個函數(shù)呢?而且竟然也運行成功了!哈哈,這就是jQuery的功勞了,jquery在處理jsonp類型的ajax時(還是忍不住吐槽,雖然jquery也把jsonp歸入了ajax,但其實它們真的不是一回事兒),自動幫你生成回調函數(shù)并把數(shù)據(jù)取出來供success屬性方法來調用,是不是很爽呀?

好啦,寫到這里,我已經(jīng)無力再寫下去,又困又累,得趕緊睡覺。朋友們要是看這不錯,覺得有啟發(fā),給點個“推薦”唄!由于實在比較簡單,所以就不再提供demo源碼下載了。

這里針對ajax與jsonp的異同再做一些補充說明:
1、ajax和jsonp這兩種技術在調用方式上“看起來”很像,目的也一樣,都是請求一個url,然后把服務器返回的數(shù)據(jù)進行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進行了封裝;
2、但ajax和jsonp其實本質上是不同的東西。ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態(tài)添加

閱讀需要支付1元查看
<