[toc]
JSON必知必會(huì)
學(xué)習(xí)網(wǎng)站:SafariBooksOnline
它是什么?
我可以用它做什么?
那些別有用心的人會(huì)用它做什么?
目錄概述:
第1~4章:JSON基礎(chǔ)知識(shí):
語(yǔ)法
語(yǔ)法驗(yàn)證
數(shù)據(jù)類型
模式驗(yàn)證
第5章:研究JSON的安全問題
介紹客戶端和服務(wù)端的概念
回答那些別有用心的人會(huì)用它做什么
第6~9章:JSON是如何在代碼中使用的
重點(diǎn)介紹了jQuery恤批、AngularJS府寒、CouchDB等技術(shù)的進(jìn)階知識(shí)
其他章節(jié): 回答JSON作為數(shù)據(jù)交換格式所扮演的種種角色凤优,我們可以使用它做什么?
章節(jié)目錄
語(yǔ)言的學(xué)習(xí)并沒有學(xué)習(xí)編程中通用的概念重要
第一章:什么是JSON受葛?
1.1 JSON是一種數(shù)據(jù)交換格式
1.2 JSON獨(dú)立于編程語(yǔ)言
1.3 專業(yè)數(shù)據(jù)和概念
筆記:
語(yǔ)言的學(xué)習(xí)并沒有學(xué)習(xí)編程中通用的概念重要
我們使用JSON题涨,即:我們使用的是一種 基于
對(duì)象表示法的 數(shù)據(jù)交換格式
JSON : JavaScript對(duì)象表示法(JavaScript Object Notation)
表示法:一個(gè)用于表示諸如數(shù)字或單詞等數(shù)據(jù)的字符系統(tǒng)
數(shù)據(jù)交換格式:用于在不同系統(tǒng)或者平臺(tái)之間交換數(shù)據(jù)的文本(所追求的重要指標(biāo):可移植性)
可移植性:在平臺(tái)系統(tǒng)之間傳輸信息的兼容性
第二章:JSON語(yǔ)法
2.1 JSON基于JavaScript對(duì)象字面量
- literal釋義
- 英語(yǔ)中 : 字面上的 :是一個(gè)形容詞, 用來表示所說的話和所表達(dá)的是其字面的意思
- 編程語(yǔ)言中: 字面量 :是一個(gè)名詞奔坟,是對(duì)數(shù)據(jù)值的具體表示
eg : x = 5 : x 表示變量 5是字面量
- JSON是基于JavaScript 對(duì)象字面量的携栋。
注意是基于搭盾,原因是:在JavaScript中咳秉,對(duì)象里面常常包含函數(shù),因此我們不能直接使用JavaScript的對(duì)象來表示鞋子具體的屬性鸯隅,還能創(chuàng)建一個(gè)walk函數(shù)澜建。而且,數(shù)據(jù)交換的核心是數(shù)據(jù)蝌以,因此JSON中不會(huì)涉及JavaScript對(duì)象字面量中的函數(shù)炕舵。
即:JSON 所基于的JavaScript對(duì)象字面量 ,單純是指對(duì)象字面量 及其屬性的語(yǔ)法表示跟畅,這種屬性的表示方法是通過名稱-值對(duì)來實(shí)現(xiàn)的咽筋。
2.2 名稱 - 值對(duì)
"animal" : "cat"
2.3 正確的JSON語(yǔ)法
名稱:始終需要被雙引號(hào)包裹。雙引號(hào)中的名稱可以是任何有效的字符串徊件。
- 推薦 :
”myAnimal“ : ”cat“
- 合法但是不推薦 :
“My animal” : ”cat“ // 名稱可以包含空格
”Library's animal“ : ”cat“ //名稱可以包含單引號(hào)
- 不推薦原因:這樣做降低了JSON數(shù)據(jù)的可移植性.
- 原因描述:JSON作為一種 基于對(duì)象表示法的
數(shù)據(jù)交換格式
奸攻,所追求的重要指標(biāo)就是可移植性
。
而使用空格和特殊字符(即 az,09除外的字符)忽略了可移植性**.因此虱痕,為了獲取最大可移植性睹耐,我們應(yīng)該盡可能的避免使用空格或者特殊字符。
值:并不總是需要被雙引號(hào)包裹部翘。
當(dāng)值是 字符串 的時(shí)候硝训,必須 使用雙引號(hào)包裹;
當(dāng)值是 數(shù)字 、布爾值窖梁、數(shù)組赘风、對(duì)象、null等其他數(shù)據(jù)類型的時(shí)候纵刘,都不應(yīng)該被雙引號(hào)包裹贝次。
構(gòu)建JSON:了解構(gòu)建一個(gè)對(duì)象的語(yǔ)法(騎士?jī)?cè)封儀式 : “JSON先生,我在此封你為對(duì)象”)
{
“animal” : "cat",
"color" : "orange"
}
-
從機(jī)器角度理解JSON語(yǔ)法
與人不同彰导,機(jī)器是完全遵守規(guī)則和指令的
蛔翅。當(dāng)我們?cè)谝粋€(gè)字符創(chuàng)類型外面使用下列字符的時(shí),實(shí)際上是告訴機(jī)器 : 如何讀取數(shù)據(jù) 的指令
位谋。- { 開始讀取對(duì)象
- } 結(jié)束讀取對(duì)象
- [ 開始讀取數(shù)組
- ] 結(jié)束讀取數(shù)組
- : 分割 名稱和值
- 山析, 一個(gè)新部分的開始
注:
例 1: 不能通過驗(yàn)證的“JSON
{
title : "This is my titile",
body : "This is my body"
}
錯(cuò)誤 : 驗(yàn)證器會(huì)拋出一個(gè) 解析錯(cuò)誤。
原因 : 名稱沒有加上雙引號(hào)掏父。如果名稱沒有加上雙引號(hào)笋轨,則表示這是一個(gè)JavaScript對(duì)象,而不是JSON赊淑。
例 2. 不合法的JSON(單引號(hào))
{
‘title’ : ‘This is my titile’,
’body‘ : ’This is my body‘
}
例 3. 合法JSON
{
"title" : "This is my titile",
”body" : "This is my body"
}
2.4 語(yǔ)法驗(yàn)證
工具:
- JSON Formatter & Validator
- JSON Editor Online
- JSONLint
2.5 JSON文件
*.json文件
2.6 JSON的媒體類型
JSON 的MIME類型是application / json
- 涉及媒體類型時(shí)機(jī) : 在傳輸數(shù)據(jù)時(shí)爵政,需要提前告知接收方數(shù)據(jù)是什么類型,這就涉及媒體類型陶缺。
- 媒體類型的別稱:如 互聯(lián)網(wǎng)媒體類型钾挟、內(nèi)容類型 或者 MIME類型。
- 表示 : 它使用 “類型/子類型”這種格式來表示饱岸,如 :text / html
第三章 JSON數(shù)據(jù)類型
提前了解并學(xué)會(huì)使用一樣事物是很有用的掺出,無論是在計(jì)算機(jī)世界中,還是在現(xiàn)實(shí)世界中苫费。
3.1 數(shù)據(jù)類型簡(jiǎn)介
原始數(shù)據(jù)類型:在不同編程語(yǔ)言中一成不變的數(shù)據(jù)類型通常叫做原始數(shù)據(jù)類型汤锨。
4.1 數(shù)據(jù)類型簡(jiǎn)介
4.1 數(shù)據(jù)類型簡(jiǎn)介
:原始數(shù)據(jù)類型*:在不同編程語(yǔ)言中一成不變的數(shù)據(jù)類型通常叫做原始數(shù)據(jù)類型。
- 數(shù)字
- 整型
- 浮點(diǎn)數(shù)
- 定點(diǎn)數(shù) - 字符和字符串
- 布爾類型
3.2 JSON中的數(shù)據(jù)類型
由于JSON是基于對(duì)象字面量表示法 以及 對(duì)象數(shù)據(jù)類型的百框,你可能覺得讓它作為數(shù)據(jù)交換格式有點(diǎn)不妥闲礼。原因是,數(shù)據(jù)交換格式:是以讓不同的兩個(gè)>系統(tǒng)之間能夠進(jìn)行交流為目的铐维,這一格式所表達(dá)的必須是共有的部分柬泽。
記住:復(fù)合數(shù)據(jù)類型對(duì)象 的 數(shù)據(jù)結(jié)構(gòu) 可以 被解構(gòu)為 原始的數(shù)據(jù)類型。
因此方椎,即使對(duì)于那些不支持對(duì)象數(shù)據(jù)類型的語(yǔ)言來說聂抢,一旦這個(gè)數(shù)據(jù)結(jié)構(gòu)能夠被解構(gòu)為 原生的數(shù)據(jù)類型,就很好處理了棠众。
JSON中的數(shù)據(jù)類型
- 對(duì)象
- 字符串
- 數(shù)字
- 布爾值
- null
- 數(shù)組
3.3 JSON中的對(duì)象數(shù)據(jù)類型
{
"person" : {
"name" : "lindsay bassett",
"head" : {
"hair" : {
"color" : "light blond",
"length" : "short"
},
"eyes" : "green"
}
}
}
3.4 JSON中的字符串類型
在JavaScript中琳疏,使用單引號(hào)或者雙引號(hào)沒有區(qū)別有决。然而,JSON不是JavaScript對(duì)象字面量空盼,它只是基于JavaScript對(duì)象字面量书幕。在JSON中,僅允許使用雙引號(hào)包裹字符串揽趾。
注意:由于JSON解析器來說` " { } 台汇,[ ] `都是解析的指令篱瞎,因此對(duì)于除了a~z ,A~Z字符構(gòu)成的字符串苟呐,JSON中對(duì)于 字符串中 其具有特殊含義 的 字符串 的識(shí)別 需要 轉(zhuǎn)譯。JSON中除了" \
還需要轉(zhuǎn)譯以下字符:
- \ / (正斜線)
- \ b (退格符)
- \ f (換頁(yè)符)
- \ t (制表符)
- \ n (換行符)
- \ r (回車符)
- \ u后面跟十六進(jìn)制字符 Unicode編碼
3.5 JSON中數(shù)字類型
- 整型俐筋、浮點(diǎn)
3.6 JSON中的布爾類型
- true / false
3.7 JSON中的null類型
對(duì)于 不存在 或者 未定義 的屬性的值牵素,使用 null 來描述。
注意 不要把null 與undefined 混淆
- undefined : 不是JSON中的數(shù)據(jù)類型澄者。
- 在JavaScript中 :
undefined 與那些 聲明的名稱 和 值 都不存在 的 對(duì)象 或者 變量 有關(guān)笆呆;
null 僅與對(duì)象 或 變量 的值有關(guān)。null 表示的是一個(gè)沒有值的值.JSON中null 必須使用 小寫形式
粱挡。
3.8 JSON中的數(shù)組類型
- 在JSON中赠幕,數(shù)組里可以包含任何支持的數(shù)據(jù)類型。
- JSON 是一種數(shù)據(jù)交換格式询筏,如果將JSON數(shù)據(jù)傳遞給一個(gè)不使用JavaScript的系統(tǒng)榕堰,那么在解析時(shí)可能出錯(cuò)。
3.9 概念
- 對(duì)象 和 數(shù)組的區(qū)別:
- 對(duì)象 是 名稱-值對(duì) 組成的 列表 或者 集合屈留。
- 數(shù)組 是 值 構(gòu)成的 列表 或者 集合局冰。數(shù)組中所有的值都應(yīng)該具有相同的 數(shù)據(jù)類型。
第四章 JSON Schema
4.1 驗(yàn)證的魔力
4.2 JSON Schema 簡(jiǎn)介
4.3 專業(yè)術(shù)語(yǔ)和概念
第五章 JSON中的安全問題
JSON本身不會(huì)構(gòu)成什么威脅灌危,因?yàn)楸旧硭褪且环N數(shù)據(jù)交換格式。它不過是一種數(shù)據(jù)文件或者數(shù)據(jù)流碳胳。真正能產(chǎn)生安全問題的是 JSON的使用勇蝙。該章節(jié)重點(diǎn)討論在
WEB中使用JSON時(shí)最常見的兩個(gè)安全問題:跨站腳本偽造
和 跨站腳本攻擊
。
5.1 客戶端和服務(wù)端的關(guān)系
舉例:
- 客戶端 就是發(fā)生在瀏覽器中的一切挨约;
- 服務(wù)端 則是發(fā)生在 運(yùn)行網(wǎng)站的 服務(wù)器 中的一切味混;
- 關(guān)系描述:互聯(lián)網(wǎng)瀏覽器(客戶端) 和 網(wǎng)站(服務(wù)端) 之間的關(guān)系 就像我們?nèi)ゲ蛷d吃飯時(shí),我們(客戶)和餐廳的關(guān)系诫惭,這一關(guān)系中包含了大量的請(qǐng)求和響應(yīng)翁锡。我們請(qǐng)求的是一份晚餐,廚房的響應(yīng)則是 將我點(diǎn)的菜做出來夕土,并送到我面前馆衔,展示給我們瘟判。
-
舉個(gè)栗子:
- 假如你正在喜歡的網(wǎng)站上看可愛的小貓的圖片,那么此時(shí)
你電腦當(dāng)上的互聯(lián)網(wǎng)瀏覽器就是客戶端角溃,而運(yùn)行著可愛小貓圖片的網(wǎng)站的電腦 就是 服務(wù)端
拷获。你的瀏覽器通過互聯(lián)網(wǎng)將你的請(qǐng)求發(fā)送給小貓圖片網(wǎng)站的服務(wù)器,服務(wù)器接著就會(huì)把對(duì)應(yīng)的頁(yè)面作為響應(yīng)發(fā)送給你减细。接下來匆瓜,你的瀏覽器就會(huì)將頁(yè)面在屏幕上渲染出來。 - 在這一關(guān)系中未蝌,我們稱
圖片網(wǎng)站返回的即將被瀏覽器處理的響應(yīng)為
客戶端的代碼驮吱;將頁(yè)面返回響應(yīng)傳遞過來之前所發(fā)生的事
,稱為服務(wù)器代碼萧吠。
- 假如你正在喜歡的網(wǎng)站上看可愛的小貓的圖片,那么此時(shí)
筆記:
我去餐廳就餐這件事情中:
我是客戶端
餐廳是服務(wù)端
我向服務(wù)員點(diǎn)餐:
我拿著我餐桌位置的標(biāo)識(shí)糠馆,向服務(wù)員描述我的需求,服務(wù)員在知道我的需求 和 我的置后怎憋,拿著我的請(qǐng)求信息向廚房發(fā)起一個(gè)請(qǐng)求又碌,廚房接收服務(wù)員傳遞過來的信
息,經(jīng)過處理加工绊袋,把對(duì)應(yīng)請(qǐng)求內(nèi)容的食物做好后毕匀,由服務(wù)員拿著我的位置信息和做好的晚餐,對(duì)我剛剛的請(qǐng)求做出一個(gè)響應(yīng)癌别,即:將食物送到我的餐桌上互拾,然后我就能夠享用了。
在這一關(guān)系中:
我 是 客戶端细疚,
餐廳 是 服務(wù)端犁柜,
廚房 是 服務(wù)器
我對(duì)應(yīng)的 餐桌 是 客戶端瀏覽器,
服務(wù)員 是 互聯(lián)網(wǎng)+瀏覽器圾笨,
我點(diǎn)的單 是 我通過瀏覽器和互聯(lián)網(wǎng) 向 服務(wù)器發(fā)送的請(qǐng)求
送到我桌子上的餐品 是 服務(wù)器給我的響應(yīng)內(nèi)容教馆,由客戶端瀏覽器解析后展示給我。
服務(wù)器給我的響應(yīng)內(nèi)容 是 客戶端代碼
服務(wù)器處理請(qǐng)求擂达,得到響應(yīng)內(nèi)容土铺,生成響應(yīng)并發(fā)送的過程,稱為 服務(wù)器代碼板鬓。
5.2 跨站請(qǐng)求偽造
跨站請(qǐng)求偽造悲敷,即:CSRF(cross-site request gorgery,讀作sea-surf),是一種利用
站點(diǎn)對(duì)用戶瀏覽器的信任
而發(fā)起攻擊的方式。CSRF漏洞已經(jīng)存在了很長(zhǎng)時(shí)間了俭令,遠(yuǎn)比JSON早后德。
攻擊原理:
- 合法JSON的不合法使用:有些合法的JSON十分危險(xiǎn),因?yàn)樗彩强梢詧?zhí)行的JS腳本抄腔。這樣黑客就能夠獲取我們的信息瓢湃。
例如:頂層JSON數(shù)組
(假設(shè)該例中的JSON中存儲(chǔ)了你的個(gè)人信息)
[
{
"user" : "zhyingjia"
},
{
"phone": "123-123-1236"
}
]
- 瀏覽器 對(duì) 不同域名的站點(diǎn) 之間 進(jìn)行資源分享有一定限制規(guī)則理张。但是使用<script></script標(biāo)簽?zāi)軌蚶@開這些規(guī)則。
例如: 黑客站點(diǎn)的<script>標(biāo)簽可能是這樣的
<script src = "[https: // www.yourspecialbank.com](https://www.yourspecialbank.com/)/user.json"></script>
- 關(guān)鍵:網(wǎng)站之間的信任憑證箱季。
上面描述的攻擊能夠得以實(shí)現(xiàn)涯穷,很關(guān)鍵的一點(diǎn)就是利用了你和網(wǎng)站間的憑證
,沒有你的憑證藏雏,<script>中的鏈接是不會(huì)返回任何東西的拷况。
原因 :<script>
中的鏈接是一個(gè)動(dòng)態(tài)鏈接,會(huì)根據(jù)登錄用戶的不同掘殴,而顯示不同的敏感信息赚瘦。
當(dāng)你在網(wǎng)站登錄時(shí),便初始化了一個(gè)憑證奏寨,網(wǎng)站以此來確定你的身份起意。
CSRF 就是利用了這一信任關(guān)系。黑客為了利用這一信任病瞳,需要在你已登錄銀行賬號(hào)的情況下訪問其他含有危險(xiǎn) <script>
標(biāo)簽的網(wǎng)站揽咕。要實(shí)現(xiàn)這點(diǎn),他事先會(huì)發(fā)送大量的偽造郵件套菜,這些郵件會(huì)偽造的和你的銀行發(fā)來的郵件一模一樣亲善,如果接受者沒有好好查看一下發(fā)件人或者郵件中的鏈接是否指向可以信任的網(wǎng)站,那么就很可能點(diǎn)進(jìn)去逗柴。
舉個(gè)例子:
如果某一天你生病了或者精神狀態(tài)不太好蛹头,不小心點(diǎn)開了這個(gè)鏈接。
如果戏溺,你這時(shí)你沒有退出銀行賬號(hào)渣蜗,那么你與銀行之間的會(huì)話仍然存在。此時(shí)你與銀行之間處于信任關(guān)系之中旷祸。
如果此時(shí)耕拷,你進(jìn)入了壞人的網(wǎng)站,即使你馬上意識(shí)到這個(gè)網(wǎng)站有點(diǎn)奇怪并且立刻關(guān)閉了它肋僧,也為時(shí)已晚了斑胜。
因?yàn)楹诳鸵呀?jīng)獲取到了敏感的 JSON 數(shù)據(jù)并發(fā)送發(fā)到了自己的服務(wù)器并且保存了起來。
那么嫌吠,如何阻止 CSRF 攻擊呢?
- 避免使用頂層 JSON 數(shù)組 :即
將數(shù)組存放到對(duì)象之中掺炭,使其成為非法的 JavaScript 辫诅,這樣包含我們敏感數(shù)據(jù)的數(shù)組就不會(huì)被 <script> 標(biāo)簽加載
例如:
{
"info" : [
{
"user" : "zhyingjia"
},
{
"phone": "123-123-1236"
}
]
}
5.3 注入攻擊
5.3.1 跨站腳本攻擊
5.3.2 安全漏洞: 決策上的失誤
5.4 專業(yè)術(shù)語(yǔ)和概念
第六章 JavaScript中的XMLHttpRequst與Web API
JavaScript中的XMLHttpRequst 與 Web API等概念聽上去好像很難,但其實(shí)并沒有那么復(fù)雜涧狮。它僅僅是一種簡(jiǎn)單的客戶端與服務(wù)端的關(guān)系:JavaScript中的XMLHttpRequest負(fù)責(zé)在客戶端發(fā)起請(qǐng)求炕矮,而WebAPI負(fù)責(zé)在服務(wù)端返回響應(yīng)么夫。
章節(jié)內(nèi)容:上一章節(jié), 我們?cè)?jīng)用餐廳的例子來說明服務(wù)端和客戶端肤视,服務(wù)端就是廚房档痪,而客戶端是來用餐的人。而和第一章關(guān)注的是其中的一類廚房邢滑,看看它是如何運(yùn)作的腐螟。
簡(jiǎn)述:
1.互聯(lián)網(wǎng)瀏覽器發(fā)送的是對(duì)某個(gè)資源的請(qǐng)求。上網(wǎng)時(shí)困后,我們通過點(diǎn)擊一個(gè)指向URL的鏈接乐纸,或者直接在瀏覽器中輸入U(xiǎn)RL。我們?cè)跒g覽器中使用的URL通常指向一個(gè)HTML資源摇予,它讓我們看到我們的網(wǎng)站汽绢。在這種情況下,我們所請(qǐng)求的資源的內(nèi)容類型是text/html.
2.另一種與我們不直接相關(guān)的客戶端-服務(wù)端關(guān)系是WebAPI侧戴。通常情況下宁昭,它所需要的是獲取數(shù)據(jù)。在這一章酗宋,我們將著眼于一種請(qǐng)求JSON資源(一種內(nèi)容為application/json)的客戶端,以及為這類顧客服務(wù)的餐廳:Web API.
6.1 WebAPI
Web API 是通過HTTP服務(wù)進(jìn)行交互的一組指令和標(biāo)準(zhǔn)积仗。這些交互可以包括:創(chuàng)建post、讀取get本缠、更新put斥扛、刪除delete (CRUD)等操作。
JavaScrip在幕后進(jìn)行這些操作丹锹,例如在某個(gè)頁(yè)面請(qǐng)求天氣數(shù)據(jù)稀颁,稱為異步操作。
異步操作:通常指發(fā)生在幕后的楣黍,不會(huì)中斷主進(jìn)程的操作匾灶。
JavaScript中的異步操作: "主進(jìn)程"指的是Web瀏覽器的顯示進(jìn)程。
例如:某個(gè)新聞頁(yè)面可能包含一個(gè)實(shí)時(shí)顯示天氣的數(shù)據(jù)的側(cè)邊欄租漂,在閱讀新聞的時(shí)候阶女,后臺(tái)代碼會(huì)每隔60s異步更新顯示數(shù)據(jù),而這一操作并不需要刷新頁(yè)面哩治,也不會(huì)對(duì)你閱讀代碼產(chǎn)生任何影響秃踩。
**AJAX與AJAJ : **Asynchronous JavaScript and XML/JSON(異步的JavaScript 和 XML/JSON).
6.2 JavaScript中的XMLHttpRequest對(duì)象
JavaScript中的XMLHttpRequest:是客戶端主動(dòng)去獲取資源的代碼。
XMLHttpRequest 描述:能夠使用HTTP協(xié)議(超文本傳輸協(xié)議)业筏,來發(fā)送請(qǐng)求的代碼 就是 XMLHttpRequest憔杨。
JavaScript中的XMLHttpRequest對(duì)象:JavaScript 是一種面向?qū)ο笳Z(yǔ)言,而 XMLHttpRequest 就是一類對(duì)象蒜胖。當(dāng)使用 new XMLHttpRequest() ,并將其返回值賦值給一個(gè)變量時(shí)消别,它就具有了從某一地址請(qǐng)求資源的功能抛蚤。
例:JavaScript中的XMLHttpRequest對(duì)象:
var myXmlHttpRequest = new XMLHttpRequest();