赞
踩
参考文章来源:JSON教程(非常详细)
目录
JSON 全称“JavaScript Object Notation”,译为“JavaScript 对象简谱”或“JavaScript 对象表示法”,是一种轻量级的、基于文本的、开放的数据交换(数据交换是指,两个设备之间建立连接并互相传递数据的过程)格式。是一种纯字符串形式的数据,它本身不提供任何方法(函数),非常适合在网络中进行传输。
2000 年初,Douglas Crockford(道格拉斯·克罗克福特)发明了 JSON,并从 2001 年开始推广使用。同年 4 月,位于旧金山湾区某车库的一台计算机发出了首个 JSON 格式的数据,这是计算机历史上的重要时刻。
图:道格拉斯·克罗克福特
2005-2006 年,JSON 正式成为主流的数据格式,雅虎、谷歌等知名网站开始广泛使用 JSON 格式。
2013 年,ECMA International(欧洲计算机制造商协会)制定了 JSON 的语法标准——ECMA-404。
经过 20 年左右的发展,JSON 已经替代了 XML,成为了 Web 开发中首选的数据交换格式。
JSON和XML都能够实现在互联网中数据传输。之所以使用 JSON,最主要的原因是 JavaScript。众所周知,JavaScript 是 Web 开发中不可或缺的技术之一,而 JSON 是基于 JavaScript 的一个子集,JavaScript 默认就支持 JSON,而且只要您学会了 JavaScript,就可以轻松地使用 JSON,不需要学习额外的知识。
JSON 数据可以存储在 .json 格式的文件中(与 .txt 格式类似,都属于纯文本文件),也可以将 JSON 数据以字符串的形式存储在数据库、Cookie、Session 中。
程序在运行时所有的变量都是存储在内存中的,将这些数据保存到数据库中,也可以保存到一个文件中,这个将内存中数据保存起来的过程称为序列化。序列化在 Python 中称为 pickling,在其他语言中也被称为 serialization、marshalling、flattening 等等,都是一个意思。
通常情况下,序列化是将程序中的对象直接转换为可保存或者可传输的数据,但这样会保存对象的类型信息,无法做到跨语言使用,例如我们使用 Python 将数据序列化到硬盘,然后使用 Java 来读取这份数据,这时由于不同编程语言的数据类型不同,就会造成读取失败。如果在序列化之前,先将对象信息转换为 JSON 格式,则不会出现此类问题。
JSON 格式的 Token 最有代表性的是 JWT(JSON Web Tokens)
JSON Web Token Introduction - jwt.io
- npm(Node.js 的包管理工具)的 package.json
- {
- "name": "server",
- "version": "0.0.0",
- "private": true,
- "main": "server.js",
- "scripts": {
- "start": "node ./bin/www"
- },
- "dependencies": {
- "cookie-parser": "~1.4.3",
- "debug": "~2.6.9",
- "express": "~4.16.0",
- "http-errors": "~1.6.2",
- "jade": "~1.11.0",
- "morgan": "~1.9.0"
- }
- }
{ }
定义。在每个键/值对中,以键开头,后跟一个冒号:
,最后是值。多个键/值对之间使用逗号,
分隔,例如{"name":"C语言中文网","url":"http://c.biancheng.net"}
;[ ]
定义,数组中每个值之间使用逗号,
进行分隔。"name":"C语言中文网"
JSON 是一种数据交换格式,可以跨语言、跨平台使用,它只是与 JavaScript 有些渊源,并不是 JavaScript 的一部分。
在 JavaScript 对象中,您既可以使用双引号也可以使用单引号,但在 JSON 中只能使用双引号。还有就是 JSON 中没有日期类型,也不能定义注释,所以您只能通过日期的字符串(例如:1970-01-01)或者时间戳(例如:1632366361)来表示日期。
语法:
// JavaScript 中的对象
{
foo: "bar"
}
// JSON
{
"foo": "bar"
}
字符串中也可以包含一些转义字符
\\
反斜线本身;\/
正斜线;\"
双引号\b
退格;\f
换页;\n
换行;\r
回车;\t
水平制表符;\u
四位的十六进制数字。JSON 中不区分整型和浮点型,只支持使用 IEEE-754 双精度浮点格式来定义数字。此外,JSON 中不能使用八进制和十六进制表示数字,但可以使用 e 或 E 来表示 10 的指数。
- {
- "number_1" : 210,
- "number_2" : -210,
- "number_3" : 21.05,
- "number_4" : 1.0E+2
- }
- {
- "message" : true,
- "pay_succeed" : false
- }
- {
- "id" : 1,
- "visibility" : true,
- "popularity" : null
- }
- {
- "author": {
- "name": "一百减一是零",
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343"
- }
- }
- {
- "course" : [
- "JSON 教程",
- "JavaScript 教程",
- "HTML 教程",
- {
- "website" : "一百减一是零",
- "url" : "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343"
- },
- [
- 3.14,
- true
- ],
- null
- ]
- }
想要在 JSON 中添加注释,我们可以在要添加注释键/值对的前面(或后面)添加一个同名的键,并在键名中添加一个特殊字符加以区分,例如@
、#
、?
、_
、/
等,然后在与键对应的值中定义注释的内容。
- {
- "@name": "网站名称",
- "name": "一百减一是零",
- "_url": "网址",
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "course": "JSON 教程",
- "@charge": "0=收费; 1=免费",
- "charge": 1,
- "#list": "教程目录",
- "list": [
- "JSON数据类型",
- "JSON对象",
- "JSON数组"
- ],
- "message": {
- "code": 0,
- "message": "OK",
- "#data": {
- "#id": "用户ID",
- "#type": "0=正常; 1=异常",
- "#name": "姓名",
- "#createTime": "创建时间(yyyy-MM-dd)"
- },
- "data": {
- "id": "12345",
- "type": 0,
- "name": "我的名字",
- "createTime": "2020-05-20"
- }
- }
- }
除了可以在键名中添加特殊字符外,也可以直接以“comment”、“_comment” 或 “__comment”作为键名来定义注释,如下例所示:
- {
- "_comment": "(https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343/)—— 一个在线学习编程的网站",
- "course": {
- "name": "JSON 教程",
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343"
- }
- }
与 JSON 相比,JSON5 做出了如下改变:
//
来定义单行注释,使用/* ... */
来定义多行注释。- {
- // 网站名称
- "name": "一百减一是零",
- // 网址
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "course": "JSON 教程",
- // 0=收费; 1=免费
- "charge": 1,
- // 教程目录
- "list": [
- "JSON数据类型",
- "JSON对象",
- "JSON数组"
- ],
- "message": {
- "code": 0,
- "message": "OK",
- /*
- id = 用户ID
- type = 0=正常; 1=异常
- name = 姓名
- createTime = 创建时间(yyyy-MM-dd)
- */
- "data": {
- "id": "12345",
- "type": 0,
- "name": "我的名字",
- "createTime": "2020-05-20"
- }
- }
- }
引入<script src="https://unpkg.com/json5@^2.0.0/dist/index.min.js"></script>
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>JavaScript</title>
- </head>
- <body>
- <script src="https://unpkg.com/json5@^2.0.0/dist/index.min.js"></script>
- <script>
- var arr = {
- // 网站名称
- "name": "一百减一是零",
- // 网址
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "course": "JSON 教程",
- // 0=收费; 1=免费
- "charge": 1,
- // 教程目录
- "list": [
- "JSON数据类型",
- "JSON对象",
- "JSON数组"
- ],
- "message": {
- "code": 0,
- "message": "OK",
- /*
- id = 用户ID
- type = 0=正常; 1=异常
- name = 姓名
- createTime = 创建时间(yyyy-MM-dd)
- */
- "data": {
- "id": "12345",
- "type": 0,
- "name": "我的名字",
- "createTime": "2020-05-20"
- }
- }
- };
- var str = JSON5.stringify(arr);
- console.log(arr)
- </script>
- </body>
- </html>
在 JSON Schema 中可以规定要在 JSON 中出现的字段、字段含义、字段类型等信息,而且可以使用 JSON Schema 来校验 JSON 数据是否符合 Schema 中定义的规范。
- {
- "$schema": "http://json-schema.org/draft-04/schema#",
- "type": "object",
- "properties": {
- "name": { "type": "string" },
- "email": { "type": "string" },
- "age": {
- "type": "number",
- "minimum": 0,
- "exclusiveMinimum": false
- },
- "telephone": {
- "type": "string",
- "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
- }
- },
- "required": ["name", "email"],
- "additionalProperties": false
- }
上面 Schema 中,要求 JSON 数据必须符合以下要求
关键字 | 描述 | 可选值 |
---|---|---|
minLength | 字符串最小长度,不能为负数 | |
maxLength | 字符串最大长度,不能为负数 | |
pattern | 正则表达式 | |
format | 字符串格式 | "date-time":日期和时间,如 2018-11-13T20:20:39+00:00 "time":时间,如 20:20:39+00:00 "date":日期,如 2018-11-13 "email":电子邮箱地址 "hostname":主机名 "ipv4":IPv4 地址 "ipv6":IPv6 地址 "uri":通用资源标识符(URI) "uri-template":URI 模板(任何级别) "regex":正则表达式 |
关键字 | 描述 | 示例 |
---|---|---|
integer | 整数 | {"type": "integer"} |
number | 数字,包括整数和浮点数 | {"type": "number"} |
multipleOf | 数字必须是给定数字(正数)的倍数 | {"type": "number", "multipleOf": 3} |
minimum | 数值允许的最小值 | {"type": "number", "minimum": 1} |
maximum | 数值允许的最大值 | {"type": "number", "maximum": 9} |
- {
- "type": "object",
- "properties": {
- "name": { "type": "string"},
- "age": {"type": "number", "multipleOf": 3},
- "date": {
- "type": "string",
- "format": "date"
- }
- }
- }
- {
- "type": "object",
- "properties": {
- "number": { "type": "number"},
- "street_name": { "type": "string"},
- "street_type": {
- "type": "string",
- "enum": ["Street", "Avenue", "Boulevard"]
- }
- },
- "additionalProperties": { "type": "string"}
- }
- {
- "type": "object",
- "properties": {
- "name": { "type": "string" },
- "email": { "type": "string" },
- "address": { "type": "string" },
- "telephone": { "type": "string" }
- },
- "required": ["name", "email"]
- }
propertyNames 定义 JSON 数据中键的命名规则
- {
- "type": "object",
- "propertyNames": {
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
- }
- }
- {
- "type": "object",
- "minProperties": 2,
- "maxProperties": 3
- }
任意长度的数组,数组中每个值都匹配相同的 Schema;
- 验证数组的所有值为数字
- {
- "type": "array",
- "items": {
- "type": "number"
- }
- }
-
- contains 关键字仅需要针对数组中的一个或多个项目进行验证,如下例所示(只需包含至少一个数字元素):
-
- {
- "type": "array",
- "contains": {
- "type": "number"
- }
- }
固定长度的数组,数组中每个值可以匹配不同的 Schema。
- 值的类型也可能是不同的,例如:
- [编号, 街道名称, 街道类型, 方向]
-
- {
- "type": "array",
- "items": [
- {
- "type": "number"
- },
- {
- "type": "string"
- },
- {
- "type": "string",
- "enum": ["Street", "Avenue", "Boulevard"]
- },
- {
- "type": "string",
- "enum": ["NW", "NE", "SW", "SE"]
- }
- ]
- }
- {
- "type": "array",
- "minItems": 2,
- "maxItems": 3
- }
- 将 uniqueItems 关键字设置为 true 可以确保数组中的每个元素都是唯一的
- {
- "type": "array",
- "uniqueItems": true
- }
{"type": "boolean"}
{"type": "null"}
- {
- "title": "Match anything",
- "description": "This is a schema that matches anything.",
- "default": "Default value",
- "examples": ["Anything", 4035]
- }
$comment 关键字用于添加注释/批注,它的值必须是一个字符串。
enum 关键字被用于定义枚举值(一组固定的值),它必须是一个至少包含一个值的数组,而且每个值都必须是唯一的。此外,type 和 enum 是并列的,必须同时满足,如下例所示:
- {
- "type": "string",
- "enum": ["red", "amber", "green"]
- }
- const 关键字被用于定义一个常量值
- {
- "properties": {
- "country": {
- "const": "United States of America"
- }
- }
- }
-
- const 是 enum 的语法糖,所以下面两个定义是等价的:
-
- { "const": "United States of America" }
- { "enum": [ "United States of America" ]}
$schema 关键字用于声明 JSON Schema 的版本,建议所有 JSON Schema 都声明一个 $schema,并且应该是 Schema 的第一个键/值对,如下例所示:
{"$schema": "http://json-schema.org/draft-04/schema#"}
如果需要声明 JSON Schema 的指定版本,则可以将 $schema 的值设置为以下几个:
$ref 关键字用于引用其他地方的一个 Schema 片段,它的值为一个 URI 引用。如果是引用同一文档的 Schema 片段,则 $ref 的值需要以井号(#)开头,例如:
{ "$ref": "#/definitions/address" }
上面示例中的“#/definitions/address”意味着:
- 转到文档的根;
- 找到 "definitions" 键的值;
- 在该对象中,找到键 "address" 的值。
如果要引用另外的 Schema 文件,可以向下面这样:
{ "$ref": "definitions.json#/address" }
示例
- {
- "$schema": "http://json-schema.org/draft-04/schema#",
- "definitions": {
- "address": {
- "type": "object",
- "properties": {
- "street_address": { "type": "string" },
- "city": { "type": "string" },
- "state": { "type": "string" }
- },
- "required": ["street_address", "city", "state"]
- }
- },
- "type": "object",
- "properties": {
- "billing_address": { "$ref": "#/definitions/address" },
- "shipping_address": { "$ref": "#/definitions/address" }
- }
- }
使用 $ref 关键字也可以引用当前 Schema 中的某一部分(类似于编程中的递归)。例如您有一个 person 模式,其中包含一个数组 children,每个数组也是一个 person 实例,如下例所示:
- {
- "$schema": "http://json-schema.org/draft-07/schema#",
- "definitions": {
- "person": {
- "type": "object",
- "properties": {
- "name": { "type": "string" },
- "children": {
- "type": "array",
- "items": { "$ref": "#/definitions/person" },
- "default": []
- }
- }
- }
- },
- "type": "object",
- "properties": {
- "person": { "$ref": "#/definitions/person" }
- }
- }
$id 关键字的值是一个 URI 引用,它有两个用途:
例如我们要引用 http://c.biancheng.net/ 域名的某个 Schema,则可以将 $id 设置为下面这样:
{ "$id": "http://c.biancheng.net/schemas/address.json" }
注意,当定义了上面所示的 $id 之后,若我们要使用 $ref 来引用同域名下的其它 Schema,则可以简写成如下所示的样子
{ "$ref": "person.json" }
XML 全称“Extensive Markup Language”,译为“可扩展标记语言”,是一种源自 SGML 的、基于文本的数据格式(XML 是 SGML 的一个子集)。是一种专门为了存储数据而创建的标记语言,它的编写方式与 HTML 非常相似,能够通过不同的标签来标记不同的内容。XML 旨在传输或保存数据,而不是显示数据,在 XML 中,没有预定义标签,其中使用的所有标签都是自定义的,而且所有的标签都由两个部分组成,分别是开始标签(例如<tagname>)和结束标签(例如</tagname>)。需要注意的是,XML 中的标签是区分大小写的
- <?xml version="1.0" encoding="ISO-8859-1"?>
- <note>
- <title>JSON教程</title>
- <author>一百减一是零</author>
- <url>https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343</url>
- <catalogue>
- <li>JSON是什么?</li>
- <li>JSONP是什么?</li>
- <li>JSON语法规则</li>
- </catalogue>
- </note>
是它可以跨平台、跨语言进行传输。另外,XML 数据可以保存在格式为 .xml 的文本文件中。
JSON | XML |
---|---|
JSON 是一种数据格式 | XML 是一种标记语言 |
与 XML 相比,JSON 数据更容易阅读 | XML 文档相对来说阅读起来比较困难 |
JSON 数据可以存储在 .json 格式的文本文件中 | XML 数据可以存储在 .xml 格式的文本文件中 |
JSON 中支持字符串、数字、数组、布尔值等类型 | XML 中只有字符串类型 |
JSON 没有显示功能 | XML 提供了显示数据的能力,因为它是一种标记语言 |
JSON 仅支持 UTF-8 编码 | XML 支持各种编码 |
JSON 不支持注释 | XML 支持注释 |
JSON 不支持命名空间 | XML 支持命名空间 |
JSON 读写速度更快,且更容易解析 | 相对于 JSON,XML 数据结构更加复杂,解析速度相对较慢 |
相对于 XML,JSON 的安全性较低 | 相对于 JSON,XML 的安全性更高 |
BSON 全称“Binary Serialized Document Format”,译为“二进制序列化文档格式”,是由 10gen(一家公司的名称)开发的一种数据格式,目前主要用于 MongoDB 数据库中,是 MongoDB 的数据存储格式。
BSON 基于 JSON,在 JSON 的基础上进行了升级,支持更多的数据类型。有时也将 BSON 称为“Binary JSON”,即“二进制 JSON”。
注意:BSON 并非只能用于 MongoDB,它也可以在其它编程语言中使用。
与 JSON 相比,BSON 存取的效率更高,而且占用的空间更小。另外,除了支持 JSON 中的数据类型外,BSON 还支持日期(Date)和二进制(BinData)等类型。
JSON 和 BSON 之间最主要的区别如下表所示:
JSON | BSON |
---|---|
JSON 是 javascript 对象表示法 | BSON 是二进制 JSON |
是一种轻量级的、基于文本的、开放的数据交换格式 | 是一种二进制序列化文档格式 |
JSON 包含一些基本数据类型,如字符串、数字、布尔值、空值 | 除了支持 JSON 中的类型外,BSON 还包含一些额外的数据类型,例如日期(Date)、二进制(BinData)等 |
AnyDB、redis 等数据库将数据存储为 JSON 格式 | MongoDB 中将数据存储为 BSON 格式 |
主要用于传输数据 | 主要用于存储数据 |
没有响应的编码和解码技术 | 有专用的编码和解码技术 |
如果想从 JSON 文件中读取指定信息,需要遍历整个数据 | 在 BSON 中,可以使用索引跳过到指定内容 |
JSON 格式不需要解析,因为它是人类可读的 | BSON 需要解析,因为它是二进制的 |
JSON 是对象和数组的组合,其中对象是键值对的集合,而数组是元素的有序列表 | BSON 是二进制数据,在其中可以存储一些附加信息,例如字符串长度、对象类型等 |
json_encode(mixed $value, int $options = 0, int $depth = 512): string | false
参数说明如下:
- $value:要转换的变量,变量可以是任意数据类型;
- $options:可选参数,默认值为 0,可选值为以下 PHP 常量:JSON_FORCE_OBJECT、JSON_HEX_QUOT、JSON_HEX_TAG、JSON_HEX_AMP、JSON_HEX_APOS、JSON_INVALID_UTF8_IGNORE、JSON_INVALID_UTF8_SUBSTITUTE、 JSON_NUMERIC_CHECK、JSON_PARTIAL_OUTPUT_ON_ERROR、JSON_PRESERVE_ZERO_FRACTION、JSON_PRETTY_PRINT、JSON_UNESCAPED_LINE_TERMINATORS、JSON_UNESCAPED_SLASHES、JSON_UNESCAPED_UNICODE、JSON_THROW_ON_ERROR。关于这些常量了解即可,一般不怎么使用,它们的具体含义您可以通过 JSON 常量查阅;
- $depth:可选参数,用来设置递归的最大深度,它的值必须大于 0,默认值为 512,同 $options 参数一样,该参数同样不怎么使用。
若转换成功,json_encode() 函数会返回字符串类型的转换结果,若转换失败,则返回 false。
示例
- <?php
- $arr = [
- "title" => "JSON教程",
- "author" => "一百减一是零",
- "url" => "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "catalogue" => [
- "JSON是什么?",
- "JSONP是什么?",
- "JSON语法规则"
- ]
- ];
- echo json_encode($arr);
- ?>
运行结果
{"title":"JSON\u6559\u7a0b","author":"C\u8bed\u8a00\u4e2d\u6587\u7f51","url":"http:\/\/c.biancheng.net\/","catalogue":["JSON\u662f\u4ec0\u4e48\uff1f","JSONP\u662f\u4ec0\u4e48\uff1f","JSON\u8bed\u6cd5\u89c4\u5219"]}
通过运行结果可以看出,在使用 json_encode() 函数将变量转换为 JSON 数据时,会将变量中的中文字符编码为 Unicode 字符(\uXXXX 格式的字符),如果不需要这样的转换,将 json_encode() 函数的第二个参数设置为 JSON_UNESCAPED_UNICODE 即可,如下例所示:
- <?php
- $arr = [
- "title" => "JSON教程",
- "author" => "一百减一是零",
- "url" => "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "catalogue" => [
- "JSON是什么?",
- "JSONP是什么?",
- "JSON语法规则"
- ]
- ];
- echo json_encode($arr,JSON_UNESCAPED_UNICODE );
- ?>
运行结果
{"title":"JSON教程","author":"C语言中文网","url":"http:\/\/c.biancheng.net\/","catalogue":["JSON是什么?","JSONP是什么?","JSON语法规则"]}
json_decode(string $json, bool $assoc = false, int $depth = 512, int $options = 0): mixed
参数说明如下:
- $json:必填参数,要解析的 JSON 字符串;
- $assoc:可选参数,默认值为 false,若将值设置为 true,那么 json_decode() 函数将返回一个数组;
- $depth:可选参数,用来设置递归的最大深度,默认值为 512,也可以设置为其它大于 0 的值;
- $options:可选参数,默认值为 0,可选值为 JSON_BIGINT_AS_STRING、JSON_INVALID_UTF8_IGNORE、JSON_INVALID_UTF8_SUBSTITUTE、JSON_OBJECT_AS_ARRAY、JSON_THROW_ON_ERROR 等常量,可以同时设置多个常量,常量之间使用竖线
|
进行分隔。有关上述常量的含义,您可以通过 PHP 预定义常量查阅。
若解析成功,json_decode() 函数会返回 JSON 中的数据,若解析失败,或者 JSON 的数据深度超过了递归的限制,则返回 null。
示例
- <?php
- $str = '{"title":"JSON教程","author":"一百减一是零","url":"https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343","catalogue":["JSON是什么?","JSONP是什么?","JSON语法规则"]}';
- echo "<pre>";
- var_dump(json_decode($str, true));
- ?>
运行结果
- array(4) {
- ["title"]=>
- string(10) "JSON教程"
- ["author"]=>
- string(16) "一百减一是零"
- ["url"]=>
- string(23) "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343"
- ["catalogue"]=>
- array(3) {
- [0]=>
- string(16) "JSON是什么?"
- [1]=>
- string(17) "JSONP是什么?"
- [2]=>
- string(16) "JSON语法规则"
- }
- }
json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)
参数说明如下:
- obj:要转换为 JSON 数据的 Python 对象;
- skipkeys:默认值为 False,如果 dict 中 keys 内的数据不是 Python 的基本类型(str、unicode、int、long、float、bool、None),会报 TypeError 错误,若设置为 True,则会跳过这类 key;
- ensure_ascii:默认值 True,即输出 ASCLL 码,若设置为 False,则可以输出中文;
- check_circular:如果值为 False,则跳过对容器类型的循环引用检查,循环引用将导致溢出错误;
- allow_nan:默认值 True,在处理 JSON 规范以外的 Float 类型时(例如:nan、inf、-inf),将其转换为 JavaScript 中的等价类型(例如:NaN、Infinity、-Infinity),若设置为 False,则会引发一个 ValueError 错误,
- cls:用来指定一个自定义的 JSONEncoder 子类,来替换 JSONCoder 类;
- indent:按照给定数值,将数据缩进显示,让数据读起来更加清晰;
- separators:分隔符,分别设置不同 dict 项之间的分隔符和 dict 项内 key 与 value 之间的分隔符,并将冒号
:
与逗号,
之后的空格全部去除;- encoding:设置 JSON 数据的编码方式,默认为 UTF-8;
- default:指定一个函数,当某个对象无法被序列化时会调用该函数;
- sort_keys:若值为 Ture,则表示按照 dict 排序(a 到 z)输出。
示例
- import json
- dictionary = {"title":"JSON教程","author":"一百减一是零","url":"https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343","catalogue":["JSON是什么?","JSONP是什么?","JSON语法规则"]}
- jsonString = json.dumps(dictionary, indent=4, ensure_ascii=False)
- print(jsonString)
运行结果
- {
- "title": "JSON教程",
- "author": "一百减一是零",
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "catalogue": [
- "JSON是什么?",
- "JSONP是什么?",
- "JSON语法规则"
- ]
- }
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
参数说明如下:
- s:要转换的 JSON 数据,可以是 str、bytes 或 bytearray 等类型;
- encoding:可选参数,设置 JSON 数据的编码方式,默认为 UTF-8;
- cls:可选参数,用于指定一个自定义 JSONCoder 的子类,来替换 JSONCoder 类;
- object_hook:可选参数,将函数的返回值替换为指定的类型,该功能可以用来实现自定义解码器,例如 JSON-RPC;
- parse_float:可选参数,如果指定该参数,那么在解码 JSON 数据时,符合 float 类型的字符串将转换为指定的类型;
- parse_int:可选参数,如果指定该参数,那么在解码 JSON 数据时,符合 int 类型的字符串将转换为指定的类型;
- parse_constant:可选参数,如果指定该参数,那么在解码 JSON 数据时,若出现 -Infinity、Infinity、NaN 等字符串,则调用指定的方法;
- object_pairs_hook:可选参数,将结果以 key-value 有序列表的形式返回,如果 object_hook 和 object_pairs_hook 同时指定的话,优先按照 object_pairs_hook 的设置返回。
示例
- import json
- json_str = '{"title":"JSON教程","author":"一百减一是零","url":"https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343","catalogue":["JSON是什么?","JSONP是什么?","JSON语法规则"]}'
- data = json.loads(json_str)
- print(data)
运行结果
{'title': 'JSON教程', 'author': '一百减一是零', 'url': 'https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343', 'catalogue': ['JSON是什么?', 'JSONP是 什么?', 'JSON语法规则']}
- import org.json.simple.JSONObject;
- class JsonEncodeDemo {
- public static void main(String[] args) {
- JSONObject obj = new JSONObject();
-
- obj.put("title", "JSON教程");
- obj.put("author", "一百减一是零");
- obj.put("url", "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343");
- obj.put("hits", 100);
-
- System.out.print(obj);
- }
- }
运行结果
{"hits":100,"author":"一百减一是零","title":"JSON教程","url":"一百减一是零-CSDN博客"}
实例
- 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{\"hits\":100,\"author\":\"一百减一是零\",\"title\":\"JSON教程\",\"url\":\"https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343\"}]";
- try{
- Object obj = parser.parse(s);
- JSONArray array = (JSONArray)obj;
- System.out.println(array.get(1));
- System.out.println();
- }catch(ParseException pe) {
- System.out.println("position: " + pe.getPosition());
- System.out.println(pe);
- }
- }
- }
运行结果
{"hits":100,"author":"一百减一是零","title":"JSON教程","url":"一百减一是零-CSDN博客"}
Ajax 全称“Asynchronous JavaScript and XML”,译为“异步 JavaScript 和 XML”,程序员们习惯称之为“阿贾克斯”,通过 Ajax 我们可以异步在服务器与客户端之间传递数据。在 Ajax 中,普遍使用 JSON 作为传输数据的格式。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta content="text/html; charset=utf-8">
- <title>AJAX And JSON</title>
- <script type="application/javascript">
- function load() {
- var url = "./data.json"; // 获取 JSON 数据的链接
- var request;
- if (window.XMLHttpRequest) {
- request = new XMLHttpRequest(); //发送 Ajax 请求,适用于 Chrome, mozilla 等浏览器
- } else if (window.ActiveXObject) {
- request = new ActiveXObject("Microsoft.XMLHTTP"); // 发送 Ajax 请求,适用于 IE 浏览器
- }
- request.onreadystatechange = function() {
- if (request.readyState == 4) {
- var jsonObj = JSON.parse(request.responseText); // 解析 JSON 数据
- document.getElementById("title").innerHTML = jsonObj.title;
- document.getElementById("author").innerHTML = jsonObj.author;
- document.getElementById("url").innerHTML = jsonObj.url;
- document.getElementById("catalogue").innerHTML = jsonObj.catalogue;
- }
- }
- request.open("GET", url, true);
- request.send();
- }
- </script>
- </head>
- <body>
- Title: <span id="title"></span><br />
- Author: <span id="author"></span><br />
- Url: <span id="url"></span><br />
- Catalogue: <span id="catalogue"></span><br />
- <button type="button" onclick="load()">点击加载 JSON 数据</button>
- </body>
- </html>
date.json 文件中的内容
- {
- "title": "JSON教程",
- "author": "一百减一是零",
- "url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343",
- "catalogue": [
- "JSON是什么?",
- "JSONP是什么?",
- "JSON语法规则"
- ]
- }
运行结果
JSONP 不是一门编程语言,也不是什么特别的技术,它更像一个漏洞,程序员可以利用这个漏洞,实现跨域(可以简单理解为跨域名)传输数据
同源策略是由 Netscape(网景)提出的一个著名的安全策略,所有支持 JavaScript 的浏览器都支持这个策略。
所谓同源是指域名、协议、端口都相同。以 http://c.biancheng.net:80/ 为例,c.biancheng.net 为域名,http 为协议,80 为端口(提示:80 为默认端口,可以省略,若为其它端口则必须显示定义)。
为了安全,浏览器不允许进行跨域请求。当我们通过 Ajax 在网页和服务器之间发送或接收数据时,需要保证网页与所请求的地址是同源的,否则无法请求成功。例如 http://c.biancheng.net/ 下的网页,只能与同在 http://c.biancheng.net/ 下的程序进行交互,无法与 https://www.baidu.com/ 下的程序进行交互。
同源策略可以防止 JavaScript 脚本从您的网站中读取数据,并将数据发送到其它的网站。如果没有同源策略,很有可能会有恶意的程序泄露您网站中的内容。
虽然同源策略在一定程度上提高了网站的安全,但也会给程序员带来一些麻烦,例如在访问一些开发接口时,由于同源策略的存在,会调用失败。要解决这种问题就需要用到跨域,跨域的方法有许多种,其中最经典的就是 JSONP。
JSONP 全称“JSON with Padding”,译为“带回调的 JSON”,它是 JSON 的一种使用模式。通过 JSONP 可以绕过浏览器的同源策略,进行跨域请求。
在进行 Ajax 请求时,由于同源策略的影响,不能进行跨域请求,而<script>
标签的 src 属性却可以加载跨域的 JavaScript 脚本,JSONP 就是利用这一特性实现的。与普通的 Ajax 请求不同,在使用 JSONP 进行跨域请求时,服务器不再返回 JSON 格式的数据,而是返回一段调用某个函数的 JavaScript 代码,在 src 属性种调用,来实现跨域。
JSONP 的优点是兼容性好,在一些老旧的浏览器种也可以运行,但它的缺点也非常明显,那就是只能进行 GET 请求。
假设我们要从网站 localhost:8080 向服务器 localhost:8081 下的发送请求,并在服务器返回如下内容:
{"name":"一百减一是零", "url":"一百减一是零-CSDN博客"}
如果直接发送 Ajax 请求,由于同源策略的存在,请求会被阻止,因为网站和服务器不同源。示例代码如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>JavaScript</title>
- </head>
- <body>
- <div id="result"></div>
- <button type="button" onclick="sendAjax()">发送请求</button>
- <script>
- function sendAjax() {
- // 创建 XMLHttpRequest 对象
- var request = new XMLHttpRequest();
- // 实例化请求对象
- request.open("GET", "http://localhost:8081/test.php");
- // 监听 readyState 的变化
- request.onreadystatechange = function() {
- // 检查请求是否成功
- if(this.readyState === 4 && this.status === 200) {
- // 将来自服务器的响应插入当前页面
- document.getElementById("result").innerHTML = this.responseText;
- }
- };
- // 将请求发送到服务器
- request.send();
- }
- </script>
- </body>
- </html>
点击页面的“发送请求”按钮,会返回如下错误:
Access to XMLHttpRequest at 'http://localhost:8081/test.php' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET http://localhost:8081/test.php net::ERR_FAILED
想要成功从服务器中获取数据,就可以使用我们上面介绍的 JSONP 来实现,实现步骤如下:
使用<script>
标签,将标签的 src 属性设置为要请求的地址,如下所示:
<script src="http://localhost:8081/test.php"></script>
这时您会发现,<script>
标签会自动解析并执行返回的内容,如果这些内容不是完整的 JavaScript 代码,程序就会报错,所有在进行 JSONP 跨域请求时,需要保证服务器返回一段完整的 JavaScript 代码。
另外,返回的内容也不能是一段纯 JSON 的数据,因为 JSON 数据会自动转换为一个 JavaScript 对象,但不将其分配给变量或者传递给函数,我们也无法拿来使用。
因此,我们可以在请求中提供一个回调函数(被作为参数传递的函数,等同于一般函数),然后通过服务器返回这个函数,并将要返回的 JSON 数据作为函数的参数一同返回,这样<script>
标签在解析并执行返回内容是就会自动调用这个函数。示例代码如下:
<script src="http://localhost:8081/test.php?callback=showJsonData"></script>
服务器 http://localhost:8081/ 的完整代码如下所示:
- <?php
- $data = array('name'=>'一百减一是零', 'url'=>'https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343'); // 定义一个数组,其中包含要返回的内容
- $callback = $_GET['callback']; // 接收请求中的回调函数
- echo $callback."(".json_encode($data).")"; // 将上面的数组转换为 JSON 格式,然后拼接到函数中,作为函数的参数,返回给前端
- return; // 阻止程序向下继续运行
- ?>
网站 localhost:8080 的完整代码如下所示:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>JavaScript</title>
- </head>
- <body>
- <script>
- function showJsonData(data){
- console.log(data);
- }
- </script>
- <script src="http://localhost:8081/test.php?callback=showJsonData"></script>
- </body>
- </html>
运行结果
{name: '一百减一是零', url: '一百减一是零-CSDN博客'}
通过 JSONP,您可以避开浏览器的同源策略,进行跨域请求。JSONP 是利用 HTML 标签的 src 属性引用资源不受同源策影响的特性来实现的,实现步骤如下:
注意:服务器返回的内容,必须是一段可执行的 JavaScript 代码,不能是其它内容。
创作不易,谢谢各位看官大佬的一键三连。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。