oh-my-docs

Summary for developers


Project maintained by italkso Hosted on GitHub Pages — Theme by mattgraham

JSON

1. JSON 是一种数据交换格式

JSON 是一种数据交换格式,完成数据交换(数据的传递);是存储数据的载体,比如基于 JSON 的 NoSQL 数据库;也可以作为配置文件,沟通人和计算机之间。当 JSON 作为配置文件放在某一个地方时,它还是在扮演着数据交换格式的角色。

从 JavaScript 对象到JSON,再到服务端的对象,数据跑了一圈。每一天,数据都在全世界各种系统中进进出出,它们的载体就是数据交换格式。在考虑使用什么数据交换格式时,数据的形式和交换数据的系统都应该被考虑到。由于多数系统都使用对象来为数据建模,所以JSON 作为数据交换格式非常流行。但 JSON 不总是最佳选择。

  1. 解决常见的安全问题

  2. 使用 JSON Schema 验证 数据格式是否正确

  3. 浏览器、Web API 和 JSON 之间的关系

  4. 服务端如何请求和创建数据

  5. 如何在 jQuery 及其他客户端框架中使用 JSON

  6. 为何 Couch NoSQL 数据库使用 JSON 存储数据

2. JSON语法及一致性验证

构建一个对象的语法

{
    "fruit":"apple",
    "color":"red"
}
语法 名称 作用
{ } 花括号 左花括号 { 表示开始读取对象,右花括号 }表示结束读取对象
[ ] 方括号 左方括号[表示开始读取数组,右方括号 ] 表示结束读取数组
: 冒号 在键-值对中分隔名称和值
, 逗号 分隔对象中的键-值对,分隔数组中的值,一个新部分的开始

JSON 中的数据类型

数据类型 说明
对象 花括号 ( { } ) 包裹的「键 - 值对的列表」,对象可以嵌套其他对象。
字符串 双引号 ( “”) 包裹,可以由任何Unicode 字符构成。
当字符串本身需要包含双引号,使用反斜线对字符串中的双引号进行转义。
数字 用于传递数据的信息片段,可以是整数、小数、负数或指数。
布尔值 truefalse (小写)
null 一个表示空值的 null 值 (null 小写)
数组 值的集合或列表,使用方括号([])包裹,用逗号分隔值。
值可以是字符串、数字、布尔值、对象或数组

示例

{
    "person":{
        "name": "Johnson Smith",
        "height": 180,
        "head": {
            "hair": {
                "color": "light blond",
                "length": "short",
                "style": "A-line"
            },
         "eyes": "brown"
        }
    }
}
{
"hello": "When I say \"Hello\", please repeat the word after me."
}
{
"story": "\\t Once upon a time, in a far away land \\n there lived a princess."
}
{
"widgetInventory": 289,
"sadSavingsAccount": 22.59,
"seattleLatitude": 47.606209,
"seattleLongitude": -122.332071,
"earthsMass": 5.97219e+24
}
{
    "toastWithBreakfast": false,
	"breadWithLunch": true
}
{
	"French": 87,
	"Japanese": null
}
{
    "fruit": [
    	"apple",
        null,
        "apple",
        null,
        "apple"
    ]
}

大多数语言都不允许变量的类型随意改变。正常情况下,在声明变量时,也需要说明它们是整型、字符串还是对象。当声明一个数组时,也要声明所有容器中所保存的数据都应是什么类型,且之后不能随意修改。JSON 作为一种数据交换格式,为了避免解析出错,应避免混合使用数据类型。

{
    "Languages": [
        "English",
        "French",
        "Japanese"
    ]
}
{
	"scores": [
		94.5,
		69.6,
		60
	]
}
{
    "answers": [
        true,
        false,
        false,
        true,
        true
    ]
}
{
    "quiz": [
        {
            "question": "What is the color of the ocean?",
            "answer": "Blue"
        },
        {
           "question": "What is JSON?",
            "answer": "JavaScript Object Notation" 
        },
        {
            "question": "There is 9 planets in the solar system.",
            "answer": false
        }
    ]
}
{
    "quiz": [
        [
            true,
            false,
            ture,
            false,
            false
        ],
        [
            true,
            true,
            ture,
            false,
            false
        ],
        [
            true,
            false,
            false,
            ture,
            false
        ]
    ]
}

使用 JSON Schema 验证数据格式的正确性

JSON 验证器只负责负责验证语法错误。验证一致性需要使用 JSON Schema。

JSON Schema

JSON Schema 解决的三个问题

使用 JSON Schema 进行一致性验证(conformity validation)的步骤

使用 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": "Your cat's age in years.",
			"minimum": 0
		},
		"declawed": {
			"type": "boolean"
		},
		"description": {
			"type": "string"
		}
	},
	"required": [
		"name",
		"age",
		"declawed"
	]
}

符合 JSON Schema 要求的合法 JSON

{
    "name": "Fluffy",
    "age": 2,
    "declawed": false
    "description": "Fluffy loves to sleep all day."
}

3. 安全使用 JSON

客户端和服务端的关系

互联网浏览器和服务器(网站)之间的关系类似客户和服务员之间的关系。

这一关系包含了大量的请求和响应。浏览器通过互联网将请求发送给服务器,服务器接着就会把对应的页面作为响应发送给浏览器,然后浏览器就会将页面在屏幕上渲染出来。

客户端就是发生在用户浏览器中的一切,而服务端则是发生在运行网站的服务器中的一切。

客户端收到的响应就是HTML、CSS 和JavaScript 代码。服务端代码是指一些服务端语言,如ASP.NET、Ruby on Rails 或 Java。

使用 JSON 可能产生的安全问题

JSON 只是文本,真正会产生安全问题的是 JSON 的使用。

在使用JSON 时,常见的安全漏洞通常发生在 JavaScript 从服务器获取到一段 JSON 字符串并将其转化为 JavaScript 对象时。

在Web 中使用 JSON 时可能会遇到以下攻击:

定位 JSON 安全问题

顶层 JSON 数组 (避免使用):

[
    {
        "user": "johonson"
    },
    {
        "phone": "555-555-5555"
    }
]

将数组作为一个值存入JSON 对象(推荐使用):

{
    "info": [
        {
            "user": "johonson"
        },
        {
            "phone": "555-555-5555"
        }
	]
}

4. XMLHttpRequest 与 Web API

JavaScript 中的 XMLHttpRequest 与 Web API 之间的关系是一种简单的客户端与服务端的关系。

5. JSON 与客户端框架

概念

jQuery 支持与JSON 交互

jQuery 框架通过缩减请求和解析JSON 的时间来缩短开发时间,从而对JSON 提供支持。

//	一个在浏览器中显示为“My Button”的按钮
<button id="myButton">My Button</button>

//	用于隐藏“My Button”的JavaScript 代码;它不会在浏览器中显示
document.getElementById("myButton").style.display = "none";

//	用于隐藏“My Button”的jQuery 代码
$("#myButton").hide();

//	jQuery 用 jQuery.parseJSON 函数解析JSON 
var myAnimal = jQuery.parseJSON('{ "animal" : "cat" }');

//	使用jQuery 仅需几行代码即可完成对JSON 数据的请求
var url = "http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139";
$.getJSON(url, function(data) {
	// 对天气数据执行一些操作
});

使用 AngularJS 创建单页应用

【例】需要将用户登录页面中的消息“Hello, stranger” 改为针对登录用户的问候语。

<h1 id="message">Hello, stranger!</h1>
if (signedIn) {
    var message = "Hello, " + userName + "!";
    document.getElementById("message").innerHTML = message;
}
<body ng-app="myApp">
    <div id="wrapper" ng-controller="myAppController">
        <h1 id="message">Hello !</h1>
    </div>  
</body>

包含userData 对象的JavaScript 控制器将被添加到全局作用域中,这会允许视图(HTML)使用该对象进行数据绑定。

angular.module('myApp', [])
	.controller('myAppController', function($scope) {
	$scope.userData = { userName : "Stranger" };
	if(signedIn)
    {
        $scope.userData = { userName : "Bob" };
    }
});

如何将保存在某个数据库中的数据放入单页应用的数据模型中是开发者要做的事。在AngularJS 数据模型中,可以使用 JSON 把数据库中的数据放到数据模型中,即通过HTTP 协议来请求JSON 数据,是一种客户端- 服务端的关系。AngularJS 通过其核心服务$http 来简化通过这一协议进行的数据模型进行的检索。

从OpenWeatherMap API 获取天气数据:

angular.module('myApp', [])
	.controller('myAppController', function($scope, $http) {
    $http.get('http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139').
	success(function(data, status, headers, config) {
		$scope.weatherData = data;
	});
});

从OpenWeatherMap API 返回的JSON 数据会被$http 反序列化。然后它将作为名为weatherData 的对象被添加到全局作用域,这样就能通过 HTML 视图的插值语法将其作为数据模型进行绑定了。

<body ng-app="myApp">
	<div id="wrapper" ng-controller="myAppController">
		<div>
			
		</div>
	</div>
</body>

6. 使用 JSON 文档存储数据

概念

不通过存储数据间的关系来存储的数据库。NoSQL 数据库有许多种,比如:

7. JSON 在服务端扮演的角色

8. 使用 JSON 作为配置文件

Node.js 默认的JavaScript 包管理器 npm 使用 JSON 作为配置文件,文件名称为package.json。内容如下:

{
    "name":"bobatron",
    "version":"1.0.0",
    "description": "The extraordinary library of Bob.",
	"main": "bob.js",
    "scripts": {
        "prepublish": "coffee -o lib/ -c src/bob.coffee"
    },
    "repository": {
		"type": "git",
		"url": "git://github.com/bobatron/bob.git"
     },
	"keywords": [
			"bob",
			"tron"
	],
    "author": "Bob Barker <bob.barker@fakemail.com> (http://bob.com/)",
	"license": "BSD-3-Clause",
	"bugs": {
	"url": "https://github.com/bobatron/issues"
	}
}
配置文件格式 可读性 表示复杂数据的能力 数据类型 解析
INI 最好    
XML 一般  
JSON 较好 便利

使用INI 格式的某游戏配置文件(settings.ini):

[general]
playIntro=false
mouseSensitivity=0.54

[display]
complexTextures=true
brightness=4.2
widgetsPerFrame=326
mode=windowed

[sound]
volume=1
effects=0.68

使用XML 格式的某游戏配置文件(settings.xml):

<?xml version="1.0" encoding="UTF-8" ?>
<settings>
    <general>
        <playIntro>false</playIntro>
		<mouseSensitivity>0.54</mouseSensitivity>
    </general>
    <dispaly>
    	<complexTextures>true</complexTextures>
		<brightness>4.2</brightness>
		<widgetsPerFrame>326</widgetsPerFrame>
    </dispaly>   
    <sound>
        <volume>1</volume>
		<effects>0.68</effects>
    </sound>
</settings>

使用JSON 格式的某游戏配置文件(settings.json):

{
    "general": {
        "playInfro": false,
        "mouseSensitivity": 0.54
    },
    "display": {
        "complexTextures": true,
		"brightness": 4.2,
		"widgetsPerFrame": 326,
        "mode": "windowed"
    },
    "sound": {
        "volume": 1,
		"effects": 0.68
    },
}

链接