JSON 基礎
簡 單地說,JSON 可以將 JavaScript 對象中表示的一組數據轉換為字符串,然后就可以在函數之間輕松地傳遞這個字符串,或者在異步應用程序中將字符串從 Web 客戶機傳遞給服務器端程序。這個字符串看起來有點兒古怪(稍后會看到幾個示例),但是 JavaScript 很容易解釋它,而且 JSON 可以表示比名稱/值對更復雜的結構。例如,可以表示數組和復雜的對象,而不僅僅是鍵和值的簡單列表。
簡單 JSON 示例
按照最簡單的形式,可以用下面這樣的 JSON 表示名稱/值對:
{ "firstName": "Brett" } |
這個示例非?;?,而且實際上比等效的純文本名稱/值對占用更多的空間:
firstName=Brett |
但是,當將多個名稱/值對串在一起時,JSON 就會體現出它的價值了。首先,可以創建包含多個名稱/值對的記錄,比如:
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" } |
從語法方面來看,這與名稱/值對相比并沒有很大的優勢,但是在這種情況下 JSON 更容易使用,而且可讀性更好。例如,它明確地表示以上三個值都是同一記錄的一部分;花括號使這些值有了某種聯系。
值的數組
當 需要表示一組值時,JSON 不但能夠提高可讀性,而且可以減少復雜性。例如,假設您希望表示一個人名列表。在 XML 中,需要許多開始標記和結束標記;如果使用典型的名稱/值對(就像在本系列前面文章中看到的那種名稱/值對),那么必須建立一種專有的數據格式,或者將鍵 名稱修改為 person1-firstName
這樣的形式。
如果使用 JSON,就只需將多個帶花括號的記錄分組在一起:
{ "people": [ |
這不難理解。在這個示例中,只有一個名為 people
的變量,值是包含三個條目的數組,每個條目是一個人的記錄,其中包含名、姓和電子郵件地址。上面的示例演示如何用括號將記錄組合成一個值。當然,可以使用相同的語法表示多個值(每個值包含多個記錄):
{ "programmers": [ |
這里最值得注意的是,能夠表示多個值,每 個值進而包含多個值。但是還應該注意,在不同的主條目(programmers、authors 和 musicians)之間,記錄中實際的名稱/值對可以不一樣。JSON 是完全動態的,允許在 JSON 結構的中間改變表示數據的方式。
在處理 JSON 格式的數據時,沒有需要遵守的預定義的約束。所以,在同樣的數據結構中,可以改變表示數據的方式,甚至可以以不同方式表示同一事物。
在 JavaScript 中使用 JSON
掌握了 JSON 格式之后,在 JavaScript 中使用它就很簡單了。JSON 是 JavaScript 原生格式,這意味著在 JavaScript 中處理 JSON 數據不需要任何特殊的 API 或工具包。
將 JSON 數據賦值給變量
例如,可以創建一個新的 JavaScript 變量,然后將 JSON 格式的數據字符串直接賦值給它:
var people = |
這非常簡單;現在 people
包含前面看到的 JSON 格式的數據。但是,這還不夠,因為訪問數據的方式似乎還不明顯。
訪問數據
盡 管看起來不明顯,但是上面的長字符串實際上只是一個數組;將這個數組放進 JavaScript 變量之后,就可以很輕松地訪問它。實際上,只需用點號表示法來表示數組元素。所以,要想訪問 programmers 列表的第一個條目的姓氏,只需在 JavaScript 中使用下面這樣的代碼:
people.programmers[0].lastName; |
注意,數組索引是從零開始的。所以,這行代碼首先訪問 people
變量中的數據;然后移動到稱為 programmers
的條目,再移動到第一個記錄([0]
);最后,訪問 lastName
鍵的值。結果是字符串值 “McLaughlin”。
下面是使用同一變量的幾個示例。
people.authors[1].genre // Value is "fantasy" |
利用這樣的語法,可以處理任何 JSON 格式的數據,而不需要使用任何額外的 JavaScript 工具包或 API。
修改 JSON 數據
正如可以用點號和括號訪問數據,也可以按照同樣的方式輕松地修改數據:
people.musicians[1].lastName = "Rachmaninov"; |
在將字符串轉換為 JavaScript 對象之后,就可以像這樣修改變量中的數據。
轉換回字符串
當然,如果不能輕松地將對象轉換回本文提到的文本格式,那么所有數據修改都沒有太大的價值。在 JavaScript 中這種轉換也很簡單:
String newJSONtext = people.toJSONString(); |
這樣就行了!現在就獲得了一個可以在任何地方使用的文本字符串,例如,可以將它用作 Ajax 應用程序中的請求字符串。
更重要的是,可以將任何 JavaScript 對象轉換為 JSON 文本。并非只能處理原來用 JSON 字符串賦值的變量。為了對名為 myObject
的對象進行轉換,只需執行相同形式的命令:
String myObjectInJSON = myObject.toJSONString(); |
這就是 JSON 與本系列討論的其他數據格式之間最大的差異。如果使用 JSON,只需調用一個簡單的函數,就可以獲得經過格式化的數據,可以直接使用了。對于其他數據格式,需要在原始數據和格式化數據之間進行轉換。即使使用 Document Object Model 這樣的 API(提供了將自己的數據結構轉換為文本的函數),也需要學習這個 API 并使用 API 的對象,而不是使用原生的 JavaScript 對象和語法。
最終結論是,如果要處理大量 JavaScript 對象,那么 JSON 幾乎肯定是一個好選擇,這樣就可以輕松地將數據轉換為可以在請求中發送給服務器端程序的格式。
互聯網的今天,AJAX已經不是什么陌生的詞匯了。說起AJAX,可能會立即想起因RSS而興起的XML。XML的解析,恐怕已經不是什么難題了,特別是 php5,大量的XML解析器的涌現,如最輕量級的SimpleXML。不過對于AJAX來說,XML的解析更傾向于前臺Javascript的支持度。 我想所有解析過XML的人,都會因樹和節點而頭大。不可否認,XML是很不錯的數據存儲方式,但是其靈活恰恰造成了其解析的困難。當然,這里所指的困難, 是相對于本文的主角--JSON而言。
JSON為何物?我就不重復概念了。通俗的說,它是一種數據的存儲格式,就像php序列化后的字符串一樣。它是一種數據描述。比如我們將一 個數組序列化后存放,就可以很容易的反序列化后應用。JSON也是如此,只不過他搭建的是客戶端Javascript和服務端php的交互橋梁。我們用 php生成JSON后的字符串,然后把這個字符串傳給前臺Javascript,Javascirpt就可以很容易的將其反JSON然后應用。說通俗點, 它真的很像數組。
言歸正傳,如何使用JSON。php5.2開始內置了JSON的支持。當然,如果低于這個版本的話,那么市面上有很多php版本的實現,隨 便下一個用就OK啦?,F在主要是說說php內置支持的JSON。很簡單,兩個函數:json_encode和json_decode(跟序列化很像啦)。 一個編碼,一個解碼。先看看編碼的使用:
<?php
$arr = array(
'name' => '陳毅鑫',
'nick' => '深空',
'contact' => array(
'email' => 'shenkong at qq dot com',
'website' => 'http://www.chenyixin.com',
)
);
$json_string = json_encode($arr);
echo $json_string;
?>
很簡單的將一個數組JSON了。需要指出的是,在非UTF-8編碼下,中文字符將不可被encode,結果會出來空值,所以,如果你使用 gb2312編寫php代碼,那么就需要將包含中文的內容使用iconv或者mb轉為UTF-8再進行json_encode,上面輸出結果如下:
{"name":"/u9648/u6bc5/u946b","nick":"/u6df1/u7a7a","contact":{"email":"shenkong at qq dot com","website":"http:////www.chenyixin.com"}}
我都說了和序列化很像,你還不信。編碼后就要解碼,php提供了相應的函數json_decode,json_decode執行后,將會得到一個對象,操作如下:
<?php
$arr = array(
'name' => '陳毅鑫',
'nick' => '深空',
'contact' => array(
'email' => 'shenkong at qq dot com',
'website' => 'http://www.chenyixin.com',
)
);
$json_string = json_encode($arr);
$obj = json_decode($json_string);
print_r($obj);
?>
訪問對象內的屬性會吧?$obj->name,這樣子的,當然,也可以把它轉位數組,方便調用啦:
$json_string = json_encode($arr);
$obj = json_decode($json_string);
$arr = (array) $obj;
print_r($arr);
php轉來轉去的用途不是特別大,除了緩存生成,感覺還不如直接存數組呢,不過,當你和前臺交互的時候,它的作用就出來咯,下面看看我怎么用Javascript來使用這段字符:
<script type="text/Javascript">
var arr = {"name":"/u9648/u6bc5/u946b","nick":"/u6df1/u7a7a","contact":{"email":"shenkong at qq dot com","website":"http:////www.chenyixin.com"}};
alert(arr.name)
</script>
上面中,直接將這個字符串賦給一個變量,它就變成一個Javascript數組了(專業化術語應該不叫數組,不過由于php的習慣問題,我就 一直叫數組好了,方便理解)。這樣,可以很方便的對arr進行遍歷或者任意做你想做的事情了。寫到這里,好像都沒提到AJAX哦?是哦,聯想一下,如果服 務端返回的responseText用JSON過的字符串代替XML的話,前臺Javascript處理起來是不是很方便呢?狗皮膏藥就是這樣用的。
其實寫到這里,除了數據的存儲格式不太一樣外,JSON和XML也沒什么太大區別哦,不過下面我說的一點。雖然和XML沒多大關系,不過, 可以說明JSON更大范圍的應用,那就是,跨域的數據調用。由于安全性問題,AJAX不支持跨域調用,這樣要調用不同域名下的數據,很麻煩哦,雖然有解決 方案(stone在他的講座上提到過了代理啊什么的雖然聽不懂但是知道能解決)。我寫兩個文件,足以展示跨域調用了。
主調文件index.html
<script type="text/Javascript">
function getProfile(str) {
var arr = str;
document.getElementById('nick').innerHTML = arr.nick;
}
</script>
<body><div id="nick"></div></body>
<script type="text/Javascript" src="http://www.openphp.cn/demo/profile.php"></script>
被調文件profile.php
<?php
$arr = array(
'name' => '陳毅鑫',
'nick' => '深空',
'contact' => array(
'email' => 'shenkong at qq dot com',
'website' => 'http://www.chenyixin.com',
)
);
$json_string = json_encode($arr);
echo "getProfile($json_string)";
?>
很顯然,當index.html調用profile.php時,JSON字符串生成,并作為參數傳入getProfile,然后將昵稱插入到div中,這樣一次跨域數據交互就完成了,是不是特別簡單。既然JSON這么簡單易用而且好用,還等什么呢?^_^
將 JSON 發給服務器 將 JSON 發給服務器并不難,但卻至關重要,而且還有一些重要的選擇要做。但是,一旦決定使用 JSON,所要做的這些選擇就會十分簡單而且數量有限,所以您需要考慮和關注的事情不多。重要的是能夠將 JSON 字符串發送給服務器,而且最好能做到盡快和盡可能簡單。 通過 GET 以名稱/值對發送 JSON 將 JSON 數據發給服務器的最簡單方法是將其轉換成文本,然后以名稱/值對的值的方式進行發送。請務必注意,JSON 格式的數據是相當長的一個對象,看起來可能會如清單 1 所示: 清單 1. JSON 格式的簡單 JavaScript 對象
如果要以名稱/值對將其發送到服務器端,應該如下所示:
這看起來不錯,但卻存在一個問題:在 JSON 數據中會有空格和各種字符,Web 瀏覽器往往要嘗試對其繼續編譯。要確保這些字符不會在服務器上(或者在將數據發送給服務器的過程中)引起混亂,需要在 JavaScript
該函數可以處理空格、斜線和其他任何可能影響瀏覽器的內容,并將它們轉換成 Web 可用字符(比如,空格會被轉換成 這種做法的缺點有兩個:
簡言之,以上是 GET 請求的兩個限制,而不是簡單的兩個與 JSON 數據相關的事情。在想要發送用戶名和姓之外的更多內容,比如表單中的選擇時,二者可能會需要多加注意。若要處理任何機密或極長的內容,可以使用 POST 請求。 利用 POST 請求發送 JSON 數據 當決定使用 POST 請求將 JSON 數據發送給服務器時,并不需要對代碼進行大量更改,如下所示:
這些代碼中的大部分,您都在 “ 掌握 Ajax,第 3 部分:Ajax 中的高級請求和響應” 中見過,應該比較熟悉,第 3 部分重點介紹了如何發送 POST 請求。請求使用 POST 而非 GET 打開,而且 Content-Type 頭被設置為讓服務器預知它能得到何種數據。在這種情況下,即為 另 一個簡單提示是 URL 的末尾追加了時間。這就確保了請求不會在它第一次被發送后即緩存,而是會在此方法每次被調用后重新創建和重發;此 URL 會由于時間戳的不同而稍微有些不同。這種技巧常被用于確保到腳本的 POST 每次都會實際生成新請求且 Web 服務器不會嘗試緩存來自服務器的響應。 JSON 就只是文本 不管使用 GET 還是 POST,關鍵之處在于 JSON 就只是文本。由于不需要特殊編碼而且每個服務器端腳本都能處理文本數據,所以可以輕松利用 JSON 并將其應用到服務器。假如 JSON 是二進制格式的或是一些怪異的文本編碼,情況就不這么簡單了;幸好 JSON 只是常規的文本數據(正如腳本能從表單提交中所接收到的數據,在 POST 段和 Content-Type 頭中亦可以看出),所以在將數據發送到服務器時無需太費心。 在服務器上解釋 JSON 一 旦您編寫完客戶端 JavaScript 代碼、允許用戶與 Web 表單和 Web 頁的交互、收集發送給服務器端程序以做處理所需的信息,此時,服務器就成為了應用程序(如果調用了異步使用的服務器端程序,則可能是我們認為的所謂的 “Ajax 應用程序”)中的主角。在此時,您在客戶端所做的選擇(比如使用 JavaScript 對象,然后將其轉換成 JSON 字符串)必須要與服務器端的選擇相匹配,比如使用哪個 API 解碼 JSON 數據。 處理 JSON 的兩步驟 不管在服務器端使用何種語言,在服務器端處理 JSON 基本上就需要兩個步驟。
以上差不多就是目前所應了解的大致內容了。接下來,我們對每個步驟進行較為詳細的介紹。 尋找 JSON 解析器 尋找 JSON 解析器或工具箱最好的資源是 JSON 站點(有關鏈接,請參閱 參考資料)。 在這里,除了可以了解此格式本身的方方面面之外,還可以通過各種鏈接找到 JSON 的各種工具和解析器,從 ASP 到 Erlang,到 Pike,再到 Ruby,應有盡有。您只需針對自己編寫腳本所用的語言下載相應的工具箱即可。為了讓服務器端腳本和程序能夠使用此工具箱,可以根據情況對其進行選擇、擴 展或安裝(如果在服務器端使用的是 C#、php 或 Lisp,則可變性更大)。 例如,如果使用的是 php,可以簡單將其升級至 php 5.2 并用它完成操作;在 php 這個最新版本默認包含了 JSON 擴展。實際上,那也是在使用 php 時處理 JSON 的最好方法。如果使用的是 Java servlet,json.org 上的 使用 JSON 解析器 一旦獲得了程序可用的資源,剩下的事就是找到合適的方法進行調用。比如,假設為 php 使用的是 JSON-php 模板:
通過該模板,可將獲得的所有數據(數組格式的、多行的、單值的或 JSON 數據結構中的任何內容)轉換成原生 php 格式,放在 如果在 servlet 中使用的是
|
php技術:有關JSON以及JSON在PHP中的應用,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。