說到AJAX就會不可避免的面臨兩個問題,
第一個是AJAX以何種格式來交換資料?
第二個是跨域的需求如何解決?
這兩個問題目前都有不同的解決方案,例如資料可以用自訂字串或用XML來描述,跨域可以透過伺服器端代理來解決。
但到目前為止最被推崇或者說首選的方案還是用JSON來傳數據,靠JSONP來跨域。而這就是本文將要講述的內容。
JSON和JSONP雖然只有一個字母的差別,但其實他們根本不是一回事:JSON是一種資料交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域數據交互協議。我們拿最近比較火的諜戰片來打個比方,JSON是地下黨們用來書寫和交換情報的“暗號”,而JSONP則是把用暗號書寫的情報傳遞給自己同志時使用的接頭方式。看到沒?一個是描述訊息的格式,一個是訊息傳遞雙方約定的方法。
什麼是JSON?
前面簡單說了一下,JSON是一種基於文字的資料交換方式,或者叫做資料描述格式,你是否該選用他首先肯定要關注它所擁有的優點。
JSON的優點:
基於純文本,跨平台傳遞極其簡單;
Javascript原生支持,後台語言幾乎全部支持;
輕量級數據格式,佔用字符數量極少,特別適合互聯網傳遞;
輕量級數據格式,佔用字符數量極少,特別適合互聯網傳遞;
可讀性較強,雖然比不上XML那麼一目了然,但在合理的依次縮進之後還是很容易識別的;
容易編寫和解析,當然前提是你要知道數據結構;
JSON的缺點當然也有,但在作者看來實在是無關緊要的東西,所以不再單獨說明。
JSON的格式或叫規則:
JSON能夠以非常簡單的方式來描述資料結構,XML能做的它都能做,因此在跨平台方面兩者完全不分伯仲。
JSON只有兩種資料型別描述符,大括號{}和方括號[],其餘英文冒號:是映射符,英文逗號,是分隔符,英文雙引號""是定義符。
大括號{}用來描述一組「不同類型的無序鍵值對集合」(每個鍵值對可以理解為OOP的屬性描述),方括號[]用來描述一組「相同類型的有序資料集合」(可對應OOP的陣列)。
上述兩種集合中若有多個子項,則透過英文逗號,進行分隔。
鍵值對以英文冒號:進行分隔,並且建議鍵名都加上英文雙引號"",以便於不同語言的解析。
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的講解有很多,但卻千篇一律,而且雲裡霧裡,對於很多剛接觸的人來講理解起來有些困難,小可不才,試著用自己的方式來闡述這個問題,看看是否有幫助。 一個眾所周知的問題,Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一律不准;不過我們又發現,Web頁面上呼叫js檔案時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有"src"這個屬性的標籤都擁有跨域的能力,比如