《JSON必知必會》學習筆記(一)

什麼是JSON

JSON全稱是Javascript Object Notation(對象表示法),是一種在不一樣平臺間傳遞數據的文本格式(數據交換格式)。常見的數據交換格式有XML、JSON兩種,咱們主要研究JSON。html

數據交換格式十分重要,開發人員須要使用它們來實現不一樣系統之間的數據交換。web

JSON基於Javascript對象字面量,可是獨立於任何編程語言,真正重要的是表示法自己,因此在學習JSON以前沒必要先學習Javascript。固然,有Javascript基礎那是再好不過了。編程

JSON語法

JSON中使用鍵值對的數據結構,示例以下:json

{
    "name": "dawei",
    "age":22,
    "isMan":true
}

名稱始終須要加上雙引號,多個鍵值對使用逗號隔開。數組

如下兩種表示方式都是錯誤的:瀏覽器

{ name: "dawei" }

這是Javascript對象而不是JSON安全

{ 'name': 'dawei' }

這也是Javascript對象,由於在Javascript對象中容許使用單引號代替雙引號。服務器

JSON數據交換格式能夠做爲獨立的文件存在於文件系統中,文件擴展名爲.json。在傳遞數據的時候須要提早告知接收方接收的數據是什麼類型。這時候就會涉及到媒體類型,也叫作內容類型或者MIME類型。常見的MIME類型是text/html,JSON的MIME類型是application/json。網絡

JSON數據類型

JSON中的數據類型包括:對象、字符串、數字、布爾值、null和數組。數據結構

對象類型

JSON中的對象類型十分簡單,JSON自己就是對象,也就是被一對花括號{}包裹的鍵值對的列表。對象能夠嵌套使用。

對象能夠包含多個鍵值對。
鍵必須是字符串,值能夠是合法的 JSON 數據類型(字符串, 數字, 對象, 數組, 布爾值或 null)。

{
    "person":{
        "name":"dawei",
        "age":23,
        "isBoy":true
    }
}

字符串類型

在JSON中字符串必須而且只能使用雙引號包裹起來。在JSON中,鍵都是字符串類型。在Javascript中,使用單引號和雙引號沒有任何區別。可是JSON不是Javascript對象字面量,它只是基於Javascript對象字面量。

對於JSON解析器來講,當一個值以雙引號開始時,它但願接下來的字符串文本以另外一個雙引號結尾。這意味着若是這段字符串自己包含雙引號可能會報錯。這時候咱們須要使用反斜槓對字符串中的雙引號進行轉義。

{
    "promo":"He say \"Bob`s the best!\" at classroom"
}

數字類型

JSON中的數字類型能夠是整數、小數、負數或者是指數。

布爾類型

JSON中的布爾值僅可以使用小寫形式:true或false,其餘任何寫法都會報錯。

null類型

在JSON中,使用null表示一無全部、不存在等意思。

對於下面這個例子,因爲對象不戴手錶,因此他不存在手錶顏色:

{
    "freckleCount":0,
    "fairy":true,
    "watchColor":null
}

數組類型

數組始終應該被方括號[]包裹。數組中的值使用逗號隔開。

這些值能夠是任何合法的JSON數據類型。因此能夠有字符串構成的數組、數字構成的數組、布爾值構成的數組、對象構成的數組甚至是數組構成的數組。

在數組中也可包含不一樣數據類型的值:

{
    "eggCarton":["egg",null,"egg",5,"egg"]
}

這在JSON中也是合法的,可是咱們應該避免這樣使用。由於若是咱們將包含不一樣數據類型的數組的JSON傳遞給一個不使用Javascript的系統,那麼在解析的時候極可能會報錯。

JSON 模式(Schema)

JSON中的數據經過互聯網或其餘網絡傳輸到接收方,接收方會對它要接收的數據有一個預期。接收方會提供一個文檔來解釋預期的格式而且提供示例。此外,JSON模式亦能夠被接收方用於傳輸方的另外一端。JSON模式每每位於要接收數據的第一行,以保證數據符合要求。

咱們統稱上述作法爲「一致性驗證」,在這裏要驗證三個方面的內容:

  • 值的類型是否正確——能夠具體規定一個值是數字、字符串等類型

  • 是否包含所須要的數據——能夠規定哪些數據是必須的,哪些是不須要的

  • 值的形式是不是咱們須要的——能夠指定範圍、最小值和最大值

JSON Schema使用JSON來書寫,一個完整的JSON Schema格式的文件以下所示:

{
    "$schema":"http://json-schema.org/draft-04/schema#",
    "title":"Cat",
    "properties":{
        "name":{
            "type":"string",
            "minLength":3,
            "maxLength":20
        },
        "age":{
            "type":"number",
            "description":"You cat's age in years.",
            "minimum":0
        },
        "declawed":{
            "type":"boolean"
        },
        "description":{
             "type":"string"
        }
    },
    "required":[
        "name",
        "age",
        "declawed"
    ]
}

在這個文件中,第一個鍵值對聲明瞭一個schema文件,第二個鍵值對是該文件的標題,第三個鍵值對是須要包含在JSON中的屬性,第四個鍵值對指定必須包含的屬性。在屬性值中,又說明了屬性類型、對屬性的描述和值的範圍。

JSON中的安全問題

JSON自己不存在任何安全問題,可是在web中使用JSON時卻常出現兩個安全問題:跨站請求僞造和跨站腳本攻擊。

跨站請求僞造

跨站請求僞造(CSRF)是一種利用站點對用戶瀏覽器的信任而發起攻擊的方式。

這個信任其實就是用戶的登陸憑證,黑客爲了獲得用戶的憑證,會在用戶登陸站點的狀況下向用戶發送大量的僞造「消息提醒」,目的就是爲了讓用戶點擊它,訪問它帶有危險腳本的網站。一旦用戶點擊這一消息提醒、訪問該惡意網站,黑客就可獲取用戶的敏感信息(登陸憑證)實現攻擊:

<script src="https://www.yourspecialbank.com/user.json"></script>

通常安全意識較差的網站使用下列這樣的JSON URL存放敏感信息:

[
    {
        "username":"dawei"
    },
    {
        "phone":"555-555-555"
    }
]

這裏的JSON格式是合法的,可是它十分危險,由於它也是可執行的JS腳本,黑客能夠輕易的將其保存到本身站點的腳本中。

如何阻止CSRF攻擊?

首先,應該將數組做爲一個值存入JSON對象,這樣數組將再也不是合法的JavaScript,腳本也就沒法加載它。

{
    "info":[
        {
            "username":"dawei"
        },
        {
            "phone":"555-555-555"
        }
    ]
}

其次,站點應該只容許post請求,靜止使用get請求。這樣黑客就沒法使用腳本中的URL了。

注入攻擊

注入攻擊都是利用系統自己的漏洞向網站注入惡意代碼來進行攻擊的。

跨站腳本攻擊

跨站腳本攻擊(XSS)是注入攻擊的一種。在使用JSON時常見的安全漏洞一般發生在Javascript從服務器獲取到一段JSON字符串並將其轉化成JavaScript對象的時候。

在JavaScript中,可使用eval()函數來進行這一操做:

var jsonString = '{"animal":"cat"}';
var myObject = eval("("+ jsonString +")");
alert(myObject.animal);

這好像沒什麼問題,可是若是服務器或者服務器發來的JSON被攻擊,攜帶了惡意代碼,這樣的話狀況將會很糟糕:

var jsonString = "alert('this is bad code')";
var myObject = eval("("+ jsonString +")");
alert(myObject.animal);

eval()的問題在於它會將傳入的字符串無差異的編譯執行,這樣的話就會給黑客以可乘之機,極可能會給咱們帶來不可估計的損失。

爲了解決這一問題,引入了JSON.parse()方法,這一函數僅解析JSON,不會執行腳本:

var jsonString = '{"animal":"cat"}';
var myObject = JSON.parse("("+ jsonString +")");
alert(myObject.animal);

未完待續...

相關文章
相關標籤/搜索