抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

JSON 指 JavaScript 对象表示法JavaScript Object Notation),是一种轻量级的数据交换格式,用于存储和交换文本信息。JSON 采用了类似 C 语言家族的习惯,易于人阅读和编写,同时也易于机器解析和生成。

JSON 在用途上类似 XML,但比 XML 更小、更快,更易解析。

简介

什么是 JSON

  • JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)。
  • JSON 是轻量级的文本数据交换格式。
  • JSON 独立于语言。
  • JSON 具有自我描述性,更易理解。

JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。目前很多动态编程语言(如 PHP、JSP、.NET)都支持 JSON。

JSON 转换为 JavaScript 对象

JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。

由于这种相似性,无需解析器,JavaScript 程序能够使用内置的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象。

JSON 是一种轻量级的基于文本的开放标准,被设计用于可读的数据交换。约定使用 JSON 的程序包括 C、C++、Java、Python、Perl 等等。

  • 用于可读的数据交换。
  • 从 JavaScript 脚本语言中演变而来。
  • 文件扩展名是 .json
  • JSON 的互联网媒体类型是 application/json

JSON 的适用范围

  • 用于编写基于 JavaScript 的应用程序,包括浏览器扩展和网站。
  • JSON 格式可以用于通过网络连接序列化和传输结构化数据。
  • 主要用于在服务器和 Web 应用程序之间传输数据。
  • Web 服务和 APIs 可以使用 JSON 格式提供公用数据。
  • 还可以用于现代编程语言中。

JSON 的特点

  • JSON 容易阅读和编写。
  • 它是一种轻量级的基于文本的交换格式。
  • 与语言无关。

简单示例

鉴于书籍数据有语言和版本信息,下面的例子展示了使用 JSON 存储书籍信息:

{
    "book": [
        {
            "id": "01",
            "language": "Java",
            "edition": "third",
            "author": "Herbert Schildt"
        },
        {
            "id": "07",
            "language": "C++",
            "edition": "second",
            "author": "E.Balagurusamy"
        }
    ]
}

与 XML 相似之处

  • JSON 是纯文本。
  • JSON 具有“自我描述性”(人类可读)。
  • JSON 具有层级结构(值中存在值)。
  • JSON 可通过 JavaScript 进行解析。
  • JSON 数据可使用 AJAX 进行传输。

与 XML 不同之处

  • 没有结束标签。
  • 更短。
  • 读写的速度更快。
  • 能够使用内建的 JavaScript eval() 方法进行解析。
  • 使用数组。
  • 不使用保留字。

为什么使用 JSON

对于 AJAX 应用程序来说,JSON 比 XML 更快更易使用:

使用 XML

  1. 读取 XML 文档;
  2. 使用 XML DOM 来循环遍历文档;
  3. 读取值并存储在变量中。

使用 JSON

  1. 读取 JSON 字符串;
  2. eval() 处理 JSON 字符串。

语法

JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。

JSON 的语法基本上可以视为 JavaScript 语法的一个子集,包括以下内容:

  • 数据使用名称-值对表示。
  • 使用大括号保存对象,每个键后面跟着一个冒号 :,名称-值对之间使用逗号 , 分隔。
  • 使用方括号保存数组,数组之间使用逗号 , 分隔。

下面是一个简单的示例:

{
    "book": [
        {
            "id": "01",
            "language": "Java",
            "edition": "third",
            "author": "Herbert Schildt"
        },
        {
            "id": "07",
            "language": "C++",
            "edition": "second",
            "author": "E.Balagurusamy"
        }
    ]
}

JSON 支持以下两种数据结构:

  • 名称-值对集合:这一数据结构由不同的编程语言支持。
  • 有序的值列表:包括数组、列表、向量或序列等等。

JSON 语法规则

JSON 语法是 JavaScript 对象表示法语法的子集。

JSON 语法规则不复杂,它参考了 C 语言家族的一些习惯,学习起来并不会感到陌生。

  • 数据在名称-值对中;
  • 数据由逗号分隔;
  • 花括号保存对象;
  • 方括号保存数组。

JSON 名称-值对

JSON 数据的书写格式是:名称-值对。

名称-值对包括字段名称(在双引号中),后面跟一个冒号,然后是值:

"firstName" : "John"

这很容易理解,等价于这条 JavaScript 语句:

firstName = "John"

JSON 值

JSON 值可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 布尔值(true 或 false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null

JSON 对象

JSON 对象在花括号中书写。对象可以包含多个名称-值对:

{
    "firstName": "John",
    "lastName": "Doe"
}

这一点也容易理解,与这条 JavaScript 语句等价:

firstName = "John";
lastName = "Doe";

JSON 数组

JSON 数组在方括号中书写。数组可包含多个对象:

{
    "employees": [
        {
            "firstName": "John",
            "lastName": "Doe"
        },
        {
            "firstName": "Anna",
            "lastName": "Smith"
        },
        {
            "firstName": "Peter",
            "lastName": "Jones"
        }
    ]
}

在上面的例子中,对象“employees”是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。

JSON 文件

  • JSON 文件的文件类型是“.json”。
  • JSON 文本的 MIME 类型是“application/json”。

JavaScript 对象转换为 JSON 文本

执行如下命令即可:

String myObjectInJSON = myObject.toJSONString();

数据类型

JSON 格式支持以下数据类型:

类型 描述
数字型(Number) JavaScript 中的双精度浮点型格式
字符串型(String) 双引号包裹的 Unicode 字符和反斜杠转义字符
布尔型(Boolean) true 或 false
数组(Array) 有序的值序列
值(Value) 可以是字符串、数字、true 或 false、null 等等
对象(Object) 无序的名称-值对集合
空格(Whitespace) 可用于任意符号对之间
null

数字型

  • JavaScript 中的双精度浮点型格式,取决于实现。
  • 不能使用八进制和十六进制格式。
  • 在数字中不能使用 NaN 和 Infinity。

下表展示了数字类型:

类型 描述
整型(Integer) 数字 1~9,0 和正负数
分数(Fraction) 分数,比如 .3、.9
指数(Exponent) 指数,比如 e,e+,e-,E,E+,E-

语法

var json-object-name = { string : number_value, … }

示例

下面的示例展示了数字类型,其值不应该使用引号包裹:

var obj = {marks: 97}

字符串型

  • 零个或多个双引号包裹的 Unicode 字符以及反斜杠转义序列。
  • 字符就是只有一个字符的字符串,长度为 1。

下表展示了字符串类型:

类型 描述
" 双引号
\ 反斜杠
/ 斜杠
\b 退格符
\f 换页符
\n 换行符
\r 回车符
\t 水平制表符
\u 四位十六进制数字

语法

var json-object-name = { string : "string value", … }

示例

下面的示例展示了字符串数据类型:

var obj = {name: 'Amit'}

布尔型

它包含 true 和 false 两个值。

语法

var json-object-name = { string : true/false, … }

示例

var obj = { name: 'Amit', marks: 97, distinction: true }

数组

  • 是一个有序的值集合。
  • 使用方括号闭合,这意味着数组以 [ 开始,以 ] 结尾。
  • 值使用逗号 , 分割。
  • 数组索引可以从 0 或 1 开始。
  • 当键名是连续的整数时应该使用数组。

语法

[ value, … ]

示例

下面的示例展示了一个包含多个对象的数组:

{
    "books": [
        {
            "language": "Java",
            "edition": "second"
        },
        {
            "language": "C++",
            "lastName": "fifth"
        },
        {
            "language": "C",
            "lastName": "third"
        }
    ]
}

对象

  • 是一个无序的名称-值对集合。
  • 对象使用大括号闭合,以 { 开始,以 } 结尾。
  • 每个名称后面都跟随一个冒号 :,名称-值对使用逗号 , 分隔。
  • 键名必须是字符串,并且不能同名。
  • 当键名是任意字符串时应该使用对象。

语法

{ string : value, … }

示例

下面的例子展示了对象:

{
    "id": "011A",
    "language": "JAVA",
    "price": 500,
}

空格

可以在任意一对符号之间插入。可以添加用来让代码更可读。下面的例子展示了使用空格和不使用空格的声明:

语法

{ string : "   ", … }

示例

var i = "   sachin";
var j = "  saurav";

null

意味着空类型。

语法

null

示例

var i = null;

if (i == 1) {
    document.write("<h1>value is 1</h1>");
} else {
    document.write("<h1>value is null</h1>");
}

JSON 基础结构

JSON 包含两种基础结构:

  1. 无序的对象结构

    无序的对象结构在不同语言中称法不同,比如在 Python 中称为字典,在 JSON 中称为 JSON 对象……

    总之就是键-值对组合形式。

  2. 有序的数组结构

    将数组作为有序数组进行转换 JSON,就可以得到有序的 JSON 数组结构。

模式

JSON 模式(Schema)是一种基于 JSON 格式定义 JSON 数据结构的规范。JSON 模式:

  • 描述现有数据格式。
  • 干净的、人类和机器可读的文档。
  • 完整的结构验证,有利于自动化测试。
  • 完整的结构验证,可用于验证客户端提交的数据。

JSON 模式示例

下面是一个基本的 JSON 模式,其中涵盖了一个经典的产品目录说明:

{
    "$schema": "https://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

我们来看一下可以用于这一模式中的各种重要关键字:

关键字 描述
$schema $schema 关键字状态,表示这个模式与 v4 规范草案书写一致。
title 用它给我们的模式提供了标题。
description 关于模式的描述。
type type 关键字在我们的 JSON 数据上定义了第一个约束:必须是一个 JSON 对象。
properties 定义各种键和它们的值类型,以及用于 JSON 文件中的最小值和最大值。
required 存放必要属性列表。
minimum 给值设置的约束条件,表示可以接受的最小值。
exclusiveMinimum 如果存在 exclusiveMinimum 并且具有布尔值 true,如果它严格意义上大于 minimum 的值则实例有效。
maximum 给值设置的约束条件,表示可以接受的最大值。
exclusiveMaximum 如果存在 exclusiveMinimum 并且具有布尔值 true,且它严格意义上小于 maximum 的值则实例有效。
multipleOf 如果通过这个关键字的值分割实例的结果是一个数字则表示紧靠 multipleOf 的数字实例是有效的。
maxLength 字符串实例字符的最大长度数值。
minLength 字符串实例字符的最小长度数值。
pattern 如果正则表达式匹配实例成功则字符串实例被认为是有效的。

可以在 JSON Schema 上检出可用于定义 JSON 模式的完整关键字列表。上面的模式可用于测试下面给出的 JSON 代码的有效性:

[
    {
        "id": 2,
        "name": "An ice sculpture",
        "price": 12.50,
    },
    {
        "id": 3,
        "name": "A blue mouse",
        "price": 25.50,
    }
]

使用

JSON 常见的应用场景是:在后台应用程序中将响应数据封装成 JSON 格式,传到前台页面之后,需要将 JSON 格式转换为 JavaScript 对象,然后在网页中使用该数据。

把 JSON 文本转换为 JavaScript 对象

JSON 最常见的用法之一,是从 Web 服务器上读取 JSON 数据(作为文件或 HttpRequest),将 JSON 数据转换为 JavaScript 对象,然后在网页中使用该数据。

下面使用字符串作为输入进行演示(而不是文件)。

实例:来自字符串的对象

创建包含 JSON 语法的 JavaScript 字符串:

var txt = '{"employees": [' +
    '{"firstName" : "John", "lastName" : "Doe"}, ' +
    '{"firstName" : "Anna", "lastName" : "Smith"}, ' +
    '{"firstName" : "Peter", "lastName" : "Jones"} ]}';

由于 JSON 语法是 JavaScript 语法的子集,JavaScript 函数 eval() 可用于将 JSON 文本转换为 JavaScript 对象。

eval() 函数使用的是 JavaScript 解释器,可解析 JSON 文本,然后生成 JavaScript 对象。必须把文本包围在括号中,这样才能避免语法错误:

var obj = eval ("(" + txt + ")");

JSON 解析器

eval() 函数可解释执行任何 JavaScript 代码。这隐藏了一个潜在的安全问题。

使用 JSON 解析器将 JSON 转换为 JavaScript 对象是更安全的做法。JSON 解析器只能识别 JSON 文本,而不会解释脚本。

浏览器提供了原生的 JSON 支持,而且 JSON 解析器的速度更快。

JSONP

JSONP(JSON with Padding)是 JSON 的一种“使用模式”,可以让网页从别的域名(网站)获取资料,即跨域读取数据。

为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP)呢?这是因为同源策略。

同源策略是由网景提出的一个著名的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。

JSONP 的实现原理是利用 <script> 标签可以获取不同源资源的特点,来达到跨域访问某个资源的目的。

JSONP 应用

服务端 JSONP 格式数据

如客户想访问 : /try/ajax/jsonp.php?jsonp=callbackFunction。

假设客户期望返回 JSON 数据:[“customername1”, “customername2”]。

真正返回到客户端的数据显示为:callbackFunction([“customername1”, “customername2”])。

服务端文件 jsonp.php 代码为:

<?php header('Content-type: application/json');
// 获取回调函数名
$jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
// JSON 数据
$json_data = '["customername1", "customername2"]';
// 输出 JSONP 格式的数据
echo $jsoncallback . "(" . $json_data . ")"; ?>

客户端实现 callbackFunction() 函数

<script type="text/javascript">
function onCustomerLoaded(result, methodName) {
    var html = '<ul>';
    for (var i = 0; i < result.length; i++) {
        html += '<li>' + result[i] + '</li>';
    }
    html += '</ul>';
    document.getElementById('divCustomers').innerHTML = html;
}
</script>

页面展示

<div id="divCustomers"></div>

客户端页面完整代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml/" >
<head>
    <title>JSONP 实例</title>
</head>
<body>
    <div id="divCustomers"></div>
    <script type="text/javascript">
        function onCustomerLoaded(result, methodName)         {
            var html = '<ul>';
            for (var i = 0; i < result.length; i++) {
                html += '<li>' + result[i] + '</li>';
            }
            html += '</ul>';
            document.getElementById('divCustomers').innerHTML = html;
        }
    </script>
<script type="text/javascript" src="/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script>
</body>
</html>

jQuery 使用 JSONP

以上代码可以使用 jQuery 代码实例:

<!DOCTYPE html>
<html>
<head>
   <title>JSONP 实例</title>
   <script src="https://apps.bdimg.com/libs/jquery/1.8.3/jquery.js"></script>
</head>
<body>
<div id="divCustomers"></div>
<script>
$.getJSON("/try/ajax/jsonp.php?jsoncallback=?", function(data) {
    var html = '<ul>';
    for(var i = 0; i < data.length; i++) {
        html += '<li>' + data[i] + '</li>';
    }
    html += '</ul>';
    $('#divCustomers').html(html);
});
</script>
</body>
</html>

在 Python 中使用 JSON

先准备环境以便针对 JSON 进行 Python 编程。

环境

在我们使用 Python 编码和解码 JSON 之前,我们需要安装一个可用 JSON 模块。我们采用 Demjson

$tar xvfz demjson-1.6.tar.gz
$cd demjson-1.6
$python setup.py install

JSON 函数

函数 程序库
encode() 将 Python 对象编码为 JSON 字符串表示。
decode() 将 JSON 编码的字符串解码为 Python 对象。

使用 Python 编码 JSON(encode)

Python 的 encode() 函数用于将 Python 对象编码为 JSON 字符串表示。

语法

demjson.encode(self, obj, nest_level = 0)

示例

下面的例子展示了使用 Python 将数组转换为 JSON:

#!/usr/bin/python
import demjson

data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ]

json = demjson.encode(data)
print json

执行时会生成如下结果:

[{"a":1,"b":2,"c":3,"d":4,"e":5}]

使用 Python 解码 JSON(decode)

Python 可以使用 demjson.decode() 函数处理 JSON 解码。这个函数返回从 JSON 解码到适当 Python 类型的值。

语法

demjson.decode(self, txt)

示例

下面的例子展示了如何使用 Python 解码 JSON 对象。

#!/usr/bin/python
import demjson

json = '{"a":1,"b":2,"c":3,"d":4,"e":5}'

text = demjson.decode(json)
print text

执行时生成如下结果:

{u'a': 1, u'c': 3, u'b': 2, u'e': 5, u'd': 4}

在 Java 中使用 JSON

先准备环境以便针对 JSON 进行 Java 编程。

环境

在我们使用 Java 编码和解码 JSON 之前,我们需要安装一个可用的 JSON 模块。我们采用 JSON.simple,然后导入 jsonsimple-1.1.1.jar 。

JSON 和 Java 实体映射

JSON.simple 实体映射从左侧到右侧为解码或解析,实体映射从右侧到左侧为编码。

JSON Java
字符串 java.lang.String
数字 java.lang.Number
bool java.lang.Boolean
null null
数组 java.util.List
对象 java.util.Map

解码时,java.util.List 的默认具体类是 org.json.simple.JSONArrayjava.util.Map 的默认具体类是 org.simple.JSONObject

在 Java 中编码 JSON

下面这个简单的示例展示了使用 java.util.HashMap 的子类 JSONObject 编码一个 JSON 对象。这里并没有提供顺序。如果需要严格的元素顺序,请使用 JSONValue.toJSONString(map) 方法的有序映射实现,比如 java.util.LinkedHashMap

import org.json.simple.JSONObject;

class JsonEncodeDemo
{
    public static void main(String[] args)
    {
        JSONObject obj = new JSONObject();

        obj.put("name", "foo");
        obj.put("num", new Integer(100));
        obj.put("balance", new Double(1000.21));
        obj.put("is_vip", new Boolean(true));

        System.out.print(obj);
    }
}

生成如下结果:

{"balance": 1000.21, "num":100, "is_vip":true, "name":"foo"}

下面是另一个示例,使用 Java JSONObject 展示了 JSON 对象流:

import org.json.simple.JSONObject;
class JsonEncodeDemo
{
    public static void main(String[] args)
    {
        JSONObject obj = new JSONObject();

        obj.put("name", "foo");
        obj.put("num", new Integer(100));
        obj.put("balance", new Double(1000.21));
        obj.put("is_vip", new Boolean(true));

        StringWriter out = new StringWriter();
        obj.writeJSONString(out);
        String jsonText = out.toString();
        System.out.print(jsonText);
    }
}

生成如下结果:

{"balance": 1000.21, "num":100, "is_vip":true, "name":"foo"}

在 Java 中解码 JSON

下面的例子使用了 JSONObject 和 JSONArray,其中 JSONObject 就是 java.util.MapJSONArray 就是 java.util.List,因此我们可以使用 Map 或 List 的标准操作访问它们。

import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
import org.json.simple.parser.ParseException;
import org.json.simple.parser.JSONParser;

class JsonDecodeDemo
{
    public static void main(String[] args)
    {
        JSONParser parser=new JSONParser();
        String s = "[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]";
        try {
            Object obj = parser.parse(s);
            JSONArray array = (JSONArray)obj;
            System.out.println("The 2nd element of array");
            System.out.println(array.get(1));
            System.out.println();
            JSONObject obj2 = (JSONObject)array.get(1);
            System.out.println("Field \"1\"");
            System.out.println(obj2.get("1"));

            s = "{}";
            obj = parser.parse(s);
            System.out.println(obj);

            s= "[5,]";
            obj = parser.parse(s);
            System.out.println(obj);

            s= "[5,,2]";
            obj = parser.parse(s);
            System.out.println(obj);
        } catch(ParseException pe) {
            System.out.println("position: " + pe.getPosition());
            System.out.println(pe);
        }
    }
}

生成如下结果:

The 2nd element of array
{"1":{"2":{"3":{"4":[5,{"6":7}]}}}}

Field "1"
{"2":{"3":{"4":[5,{"6":7}]}}}
{}
[5]
[5,2]

评论