JSON教程(非常详细)

参考文章来源:JSON教程(非常详细)

目录

JSON

JSON 发展史

为什么要使用 JSON?

JSON 的不足

存储格式

使用场景

1) 定义接口

2) 序列化

3) 生成 Token

4) 配置文件

JSON语法规则

JSON 与 JavaScript 对象的区别

JSON数据类型

1、字符串

2、数字

3、布尔值

4、空

5、对象

6、数组

JSON注释

JSON5 

前端使用

示例

运行结果

JSON Schema

定义 Schema

Schema 中提供了一系列关键字

        1) 字符串(String)

        2) 数值类型

        3) 对象        

                属性(Properties)

                额外属性(Asdditional Properties)

                必须属性(Required Properties)

                属性名称(Property names)

                属性个数(Size)

4) 数组

列表验证(List validation)

元组验证(Tuple validation)

数组长度(Length)

唯一(Uniqueness)

5) 布尔(boolean)

6) 空值(null)

7) 通用关键字

注释(Comments)

枚举值(Enumerated values)

常量值(Constant values)

8) $schema 关键字

9) $ref 关键字

10) $id 关键字

JSON和XML的区别

什么是 XML?

样例

优点

JSON 与 XML 之间的差异

JSON和BSON的区别

什么是 BSON?

JSON 与 BSON 之间的区别

不同语言的解析和创建

PHP 

json_encode()

json_decode()

Python 

json.dumps()

json.loads()

Java 

使用 Java 解析 JSON 数据

Ajax

扩展知识JSONP是什么?

同源策略

什么是 JSONP?

如何实现 JSONP

总结


JSON

JSON 全称“JavaScript Object Notation”,译为“JavaScript 对象简谱”或“JavaScript 对象表示法”,是一种轻量级的、基于文本的、开放的数据交换(数据交换是指,两个设备之间建立连接并互相传递数据的过程)格式。是一种纯字符串形式的数据,它本身不提供任何方法(函数),非常适合在网络中进行传输。

JSON 发展史

2000 年初,Douglas Crockford(道格拉斯·克罗克福特)发明了 JSON,并从 2001 年开始推广使用。同年 4 月,位于旧金山湾区某车库的一台计算机发出了首个 JSON 格式的数据,这是计算机历史上的重要时刻。
 

道格拉斯·克罗克福特


图:道格拉斯·克罗克福特
2005-2006 年,JSON 正式成为主流的数据格式,雅虎、谷歌等知名网站开始广泛使用 JSON 格式。
2013 年,ECMA International(欧洲计算机制造商协会)制定了 JSON 的语法标准——ECMA-404。
经过 20 年左右的发展,JSON 已经替代了 XML,成为了 Web 开发中首选的数据交换格式。

为什么要使用 JSON?

 JSON和XML都能够实现在互联网中数据传输。之所以使用 JSON,最主要的原因是 JavaScript。众所周知,JavaScript 是 Web 开发中不可或缺的技术之一,而 JSON 是基于 JavaScript 的一个子集,JavaScript 默认就支持 JSON,而且只要您学会了 JavaScript,就可以轻松地使用 JSON,不需要学习额外的知识。

  • 结构简单、紧凑:与 XML 相比,JSON 遵循简单、紧凑的风格,有利于程序员编辑和阅读,而 XML 相对比较复杂;
  • 更快:JSON 的解析速度比 XML 更快(因为 XML 与 HTML 很像,在解析大型 XML 文件时需要消耗额外的内存),存储同样的数据,JSON 格式所占的存储空间更小;
  • 可读性高:JSON 的结构有利于程序员阅读。

JSON 的不足

  • 只有一种数字类型:JSON 中只支持 IEEE-754 双精度浮点格式,因此您无法使用 JSON 来存储许多编程语言中多样化的数字类型;
  • 没有日期类型:在 JSON 中您只能通过日期的字符串(例如:1970-01-01)或者时间戳(例如:1632366361)来表示日期;
  • 没有注释:在 JSON 中无法添加注释;
  • 冗长:虽然 JSON 比 XML 更加简洁,但它并不是最简洁的数据交换格式,对于数据量庞大或用途特殊的服务,您需要使用更加高效的数据格式。

存储格式

JSON 数据可以存储在 .json 格式的文件中(与 .txt 格式类似,都属于纯文本文件),也可以将 JSON 数据以字符串的形式存储在数据库、Cookie、Session 中。
 

使用场景

1) 定义接口
  • 使用 Ajax 异步加载的数据;
  • RPC 远程调用;
  • 前后端分离,后端返回的数据;
  • 开发 API,例如百度、高德的一些开放接口。
2) 序列化

程序在运行时所有的变量都是存储在内存中的,将这些数据保存到数据库中,也可以保存到一个文件中,这个将内存中数据保存起来的过程称为序列化。序列化在 Python 中称为 pickling,在其他语言中也被称为 serialization、marshalling、flattening 等等,都是一个意思。

通常情况下,序列化是将程序中的对象直接转换为可保存或者可传输的数据,但这样会保存对象的类型信息,无法做到跨语言使用,例如我们使用 Python 将数据序列化到硬盘,然后使用 Java 来读取这份数据,这时由于不同编程语言的数据类型不同,就会造成读取失败。如果在序列化之前,先将对象信息转换为 JSON 格式,则不会出现此类问题。

3) 生成 Token

JSON 格式的 Token 最有代表性的是 JWT(JSON Web Tokens)
JSON Web Token Introduction - jwt.io

4) 配置文件
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"}
}

JSON语法规则

  • Object(对象):键/值对(名称/值)的集合,使用花括号{ }定义。在每个键/值对中,以键开头,后跟一个冒号:,最后是值。多个键/值对之间使用逗号,分隔,例如{"name":"C语言中文网","url":"http://c.biancheng.net"}
  • Array(数组):值的有序集合,使用方括号[ ]定义,数组中每个值之间使用逗号,进行分隔。
  • 键:JSON 数据是以键/值对(名称/值)的形式书写的,键表示数据的名称,需要以字符串的形式定义(在双引号中定义),后面紧跟一个冒号,最后是值,如下例所示:

    "name":"C语言中文网"

  • 值:支持很多数据类型。
    • 数字(整数或浮点数);
    • 字符串(需要在双引号中定义);
    • 布尔值(true 或 false);
    • 数组(在方括号中定义);
    • 对象(在花括号中定义);
    • null(空)。

JSON 与 JavaScript 对象的区别

JSON 是一种数据交换格式,可以跨语言、跨平台使用,它只是与 JavaScript 有些渊源,并不是 JavaScript 的一部分。

在 JavaScript 对象中,您既可以使用双引号也可以使用单引号,但在 JSON 中只能使用双引号。还有就是 JSON 中没有日期类型,也不能定义注释,所以您只能通过日期的字符串(例如:1970-01-01)或者时间戳(例如:1632366361)来表示日期。

语法:

// JavaScript 中的对象
{
    foo: "bar"
}

// JSON
{
    "foo": "bar"
}

JSON数据类型

1、字符串

字符串中也可以包含一些转义字符

  • \\反斜线本身;
  • \/正斜线;
  • \"双引号
  • \b退格;
  • \f换页;
  • \n换行;
  • \r回车;
  • \t水平制表符;
  • \u四位的十六进制数字。

2、数字

JSON 中不区分整型和浮点型,只支持使用 IEEE-754 双精度浮点格式来定义数字。此外,JSON 中不能使用八进制和十六进制表示数字,但可以使用 e 或 E 来表示 10 的指数。

{"number_1" : 210,"number_2" : -210,"number_3" : 21.05,"number_4" : 1.0E+2
}

3、布尔值

{"message" : true,"pay_succeed" : false
}

4、空

{"id" : 1,"visibility" : true,"popularity" : null
}

5、对象

{"author": {"name": "一百减一是零","url": "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343"}
}

6、数组

{"course" : ["JSON 教程","JavaScript 教程","HTML 教程",{"website" : "一百减一是零","url" : "https://blog.csdn.net/weixin_59383491?spm=1000.2115.3001.5343"},[3.14,true],null]
}

JSON注释

想要在 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"}
}

JSON5 

与 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 = 用户IDtype = 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 = 用户IDtype = 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 Schema 中可以规定要在 JSON 中出现的字段、字段含义、字段类型等信息,而且可以使用 JSON Schema 来校验 JSON 数据是否符合 Schema 中定义的规范。

定义 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 数据必须符合以下要求

  • 类型为 object;
  • JSON 中可以包含以下四个键:
    • name:必须是字符串类型;
    • email:必须是字符串类型;
    • age:必须是大于 0 的整数;
    • telephone:必须是字符串类型,并且需要匹配指定的正则表达式。
  • 上面的四个键中,name 和 email 必须定义,而 age 和 telephone 则是可选的;
  • 除了上面四个键,不允许出现其它的键。

Schema 中提供了一系列关键字

        1) 字符串(String)

关键字描述可选值
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":正则表达式

        2) 数值类型

关键字描述示例
integer整数{"type": "integer"}
number数字,包括整数和浮点数{"type": "number"}
multipleOf数字必须是给定数字(正数)的倍数{"type": "number", "multipleOf": 3}
minimum数值允许的最小值{"type": "number", "minimum": 1}
maximum数值允许的最大值{"type": "number", "maximum": 9}

        3) 对象        

                属性(Properties)
{"type": "object","properties": {"name": { "type": "string"},"age": {"type": "number", "multipleOf": 3},"date": {"type": "string","format": "date"}}
}
                额外属性(Asdditional Properties)
{"type": "object","properties": {"number": { "type": "number"},"street_name": { "type": "string"},"street_type": {"type": "string","enum": ["Street", "Avenue", "Boulevard"]}},"additionalProperties": { "type": "string"}
}
                必须属性(Required Properties)
{"type": "object","properties": {"name": { "type": "string" },"email": { "type": "string" },"address": { "type": "string" },"telephone": { "type": "string" }},"required": ["name", "email"]
}
                属性名称(Property names)

propertyNames 定义 JSON 数据中键的命名规则

{"type": "object","propertyNames": {"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"}
}
                属性个数(Size)
{"type": "object","minProperties": 2,"maxProperties": 3
}

4) 数组

列表验证(List validation)

任意长度的数组,数组中每个值都匹配相同的 Schema;

验证数组的所有值为数字
{"type": "array","items": {"type": "number"}
}contains 关键字仅需要针对数组中的一个或多个项目进行验证,如下例所示(只需包含至少一个数字元素):{"type": "array","contains": {"type": "number"}
}
元组验证(Tuple validation)

固定长度的数组,数组中每个值可以匹配不同的 Schema。

值的类型也可能是不同的,例如:
[编号, 街道名称, 街道类型, 方向]{"type": "array","items": [{"type": "number"},{"type": "string"},{"type": "string","enum": ["Street", "Avenue", "Boulevard"]},{"type": "string","enum": ["NW", "NE", "SW", "SE"]}]
}
数组长度(Length)
{"type": "array","minItems": 2,"maxItems": 3
}
唯一(Uniqueness)
将 uniqueItems 关键字设置为 true 可以确保数组中的每个元素都是唯一的
{"type": "array","uniqueItems": true
}

5) 布尔(boolean)

{"type": "boolean"}

6) 空值(null)

{"type": "null"}

7) 通用关键字

  • title 和 description 关键字必须是字符串,“title”最好比较简短,而“description”应该提供关于该 schema 的详细描述;
  • default 关键字用来定义默认值;
  • examples 关键字是用于提供一系列针对该模式进行验证的示例。
{"title": "Match anything","description": "This is a schema that matches anything.","default": "Default value","examples": ["Anything", 4035]
}

注释(Comments)

$comment 关键字用于添加注释/批注,它的值必须是一个字符串。

枚举值(Enumerated values)

enum 关键字被用于定义枚举值(一组固定的值),它必须是一个至少包含一个值的数组,而且每个值都必须是唯一的。此外,type 和 enum 是并列的,必须同时满足,如下例所示:

{"type": "string","enum": ["red", "amber", "green"]
}

常量值(Constant values)

const 关键字被用于定义一个常量值
{"properties": {"country": {"const": "United States of America"}}
}const 是 enum 的语法糖,所以下面两个定义是等价的:{ "const": "United States of America" }
{ "enum": [ "United States of America" ]}

8) $schema 关键字

$schema 关键字用于声明 JSON Schema 的版本,建议所有 JSON Schema 都声明一个 $schema,并且应该是 Schema 的第一个键/值对,如下例所示:

{"$schema": "http://json-schema.org/draft-04/schema#"}

如果需要声明 JSON Schema 的指定版本,则可以将 $schema 的值设置为以下几个:

  • http://json-schema.org/draft-07/schema#
  • http://json-schema.org/draft-06/schema#
  • http://json-schema.org/draft-04/schema#

9) $ref 关键字

$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" }}
}

10) $id 关键字

 $id 关键字的值是一个 URI 引用,它有两个用途:

  • 为 Schema 声明一个唯一的标识符;
  • 声明一个基本 URI,$ref 可以基于该 URI 进行引用。


例如我们要引用 http://c.biancheng.net/ 域名的某个 Schema,则可以将 $id 设置为下面这样:

{ "$id": "http://c.biancheng.net/schemas/address.json" }

注意,当定义了上面所示的 $id 之后,若我们要使用 $ref 来引用同域名下的其它 Schema,则可以简写成如下所示的样子

{ "$ref": "person.json" }

JSON和XML的区别

什么是 XML?

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 之间的差异

JSONXML
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 的安全性更高

JSON和BSON的区别

什么是 BSON?

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 之间最主要的区别如下表所示:
 

JSONBSON
JSON 是 javascript 对象表示法BSON 是二进制 JSON
是一种轻量级的、基于文本的、开放的数据交换格式是一种二进制序列化文档格式
JSON 包含一些基本数据类型,如字符串、数字、布尔值、空值除了支持 JSON 中的类型外,BSON 还包含一些额外的数据类型,例如日期(Date)、二进制(BinData)等
AnyDB、redis 等数据库将数据存储为 JSON 格式MongoDB 中将数据存储为 BSON 格式
主要用于传输数据主要用于存储数据
没有响应的编码和解码技术有专用的编码和解码技术
如果想从 JSON 文件中读取指定信息,需要遍历整个数据在 BSON 中,可以使用索引跳过到指定内容
JSON 格式不需要解析,因为它是人类可读的BSON 需要解析,因为它是二进制的
JSON 是对象和数组的组合,其中对象是键值对的集合,而数组是元素的有序列表BSON 是二进制数据,在其中可以存储一些附加信息,例如字符串长度、对象类型等

不同语言的解析和创建

PHP 

  • json_encode():可以将变量转换为 JSON 格式;
  • json_decode():可以对 JSON 格式的字符串进行解析。

json_encode()

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()

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语法规则"}
}

Python 

  • json.dumps():将 Python 对象转换为 JSON 数据;
  • json.loads():将 JSON 数据解析为 Python 对象。

json.dumps()

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()

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语法规则']}

Java 

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博客"}

使用 Java 解析 JSON 数据

实例

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

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是什么?

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?

JSONP 全称“JSON with Padding”,译为“带回调的 JSON”,它是 JSON 的一种使用模式。通过 JSONP 可以绕过浏览器的同源策略,进行跨域请求。

在进行 Ajax 请求时,由于同源策略的影响,不能进行跨域请求,而<script>标签的 src 属性却可以加载跨域的 JavaScript 脚本,JSONP 就是利用这一特性实现的。与普通的 Ajax 请求不同,在使用 JSONP 进行跨域请求时,服务器不再返回 JSON 格式的数据,而是返回一段调用某个函数的 JavaScript 代码,在 src 属性种调用,来实现跨域。

JSONP 的优点是兼容性好,在一些老旧的浏览器种也可以运行,但它的缺点也非常明显,那就是只能进行 GET 请求。

如何实现 JSONP

假设我们要从网站 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 属性引用资源不受同源策影响的特性来实现的,实现步骤如下:

  • 在请求地址中拼接一个回调函数,得到一个新的地址,将这个新地址赋值给 <script> 标签的 src 属性;
  • 服务器接收这个回调函数,并向函数中注入参数,然后以字符串的形式返回这个函数以及其中的参数;
  • <script> 在接收到返回内容后,会将内容当作是一段 JavaScript 代码,自动执行。

注意:服务器返回的内容,必须是一段可执行的 JavaScript 代码,不能是其它内容。

创作不易,谢谢各位看官大佬的一键三连。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/317629.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第7篇:创建Nios II工程之控制LED<二>

Q&#xff1a;上一期我们完成了Quartus硬件工程部分&#xff0c;本期我们创建Nios II软件工程这部分。 A&#xff1a;创建完BSP和Nios II Application之后&#xff0c;在source文件main.c中添加LED控制代码&#xff1a;system.h头文件包含了Platform Designer系统中IP的硬件信…

Kubernetes - CentOS7搭建k8s_v1.18集群高可用(kubeadm/二进制包部署方式)实测配置验证手册

Kubernetes - CentOS7搭建k8s集群高可用&#xff08;kubeadm/二进制包部署方式&#xff09;实测配置验证手册 前言概述&#xff1a; 一、Kubernetes—k8s是什么 Kubernetes 这个名字源于希腊语&#xff0c;意为“舵手“或”飞行员"。 Kubernetes&#xff0c;简称K8s&#…

Qwen-Audio:推动通用音频理解的统一大规模音频-语言模型(开源)

随着人工智能技术的不断进步&#xff0c;音频语言模型&#xff08;Audio-Language Models&#xff09;在人机交互领域变得越来越重要。然而&#xff0c;由于缺乏能够处理多样化音频类型和任务的预训练模型&#xff0c;该领域的进展受到了限制。为了克服这一挑战&#xff0c;研究…

51单片机入门(一)

1. 51单片机的基础介绍 2. RAM和ROM的区别 总体而言&#xff0c;RAM和ROM在计算机系统中起着不同的角色&#xff0c;RAM用于临时存储运行时数据&#xff0c;而ROM用于存储永久性的固件和系统程序。 3. 为什么叫51单片机 因为51系列单片机都是使用Intel 8031指令系统的单片机…

太速科技-多路PCIe的阵列计算全国产化服务器

多路PCIe的阵列计算全国产化服务器 多路PCIe的阵列计算全国产化服务器以国产化处理器&#xff08;海光、飞腾ARM、算能RSIC V&#xff09;为主板&#xff0c;扩展6-8路PCIe3.0X4计算卡&#xff1b; 计算卡为全国产化的AI处理卡&#xff08;瑞星微ARM&#xff0c;算能AI&#x…

《QT实用小工具·五十》动态增删数据与平滑缩放移动的折线图

1、概述 源码放在文章末尾 该项目实现了带动画、带交互的折线图&#xff0c;包含如下特点&#xff1a; 动态增删数值 自适应显示坐标轴数值 鼠标悬浮显示十字对准线 鼠标靠近点自动贴附 支持直线与平滑曲线效果 自定义点的显示类型与大小 自适应点的数值显示位置 根据指定锚点…

如何讲好ppt演讲技巧(4篇)

如何讲好ppt演讲技巧&#xff08;4篇&#xff09; 如何讲好PPT演讲技巧&#xff08;四篇&#xff09; **篇&#xff1a;精心准备&#xff0c;奠定演讲基础 一个成功的PPT演讲&#xff0c;离不开精心的准备。首先&#xff0c;要确定演讲的主题和目标&#xff0c;确保演讲内容清…

字典及GitHub字典爬取工具

红队API接口Fuzz字典可以用于WEB安全&#xff0c;渗透测试&#xff0c;SRC等场景 完整文件已上传知识星球&#xff0c;需要的朋友可加入查看。

Docker容器---Harbor私有仓库部署与管理

一、搭建本地私有仓库 1、下载registry镜像 [rootlocalhost ~]#docker pull registry Using default tag: latest latest: Pulling from library/registry 79e9f2f55bf5: Pull complete 0d96da54f60b: Pull complete 5b27040df4a2: Pull complete e2ead8259a04: Pull comp…

OPPO Reno10Pro/Reno11/K10手机强解BL刷root权限KSU内核抓包刷机救砖

OPPO Reno10Pro/Reno11/K10手机虽然发布时间并不久&#xff0c;但由于天玑处理器的体质&#xff0c;已经支持强制解锁BL了&#xff0c;该漏洞来自第三方工具适配&#xff0c;支持OPPO天机8100/8200刷机救砖解锁BL不需要等待官方深度测试直接实现。解锁BL后的OPPO Reno10Pro/Ren…

Android binder死亡通知机制

在Andorid 的binder系统中&#xff0c;当Bn端由于种种原因死亡时&#xff0c;需要通知Bp端&#xff0c;Bp端感知Bn端死亡后&#xff0c;做相应的处理。 使用 Bp需要先注册一个死亡通知&#xff0c;当Bn端死亡时&#xff0c;回调到Bp端。 1&#xff0c;java代码注册死亡通知 …

hadoop学习---基于hive的航空公司客户价值的LRFCM模型案例

案例需求&#xff1a; RFM模型的复习 在客户分类中&#xff0c;RFM模型是一个经典的分类模型&#xff0c;模型利用通用交易环节中最核心的三个维度——最近消费(Recency)、消费频率(Frequency)、消费金额(Monetary)细分客户群体&#xff0c;从而分析不同群体的客户价值。在某些…

C++list的模拟实现

文章目录 一、观察源码二、模拟实现1. 节点结构体2. list类3. 迭代器的定义与实现&#xff08;1&#xff09; 前置--后置--模拟实现&#xff08;2&#xff09; *和->重载模拟实现&#xff08;3&#xff09; 和!重载实现 4. list成员函数模拟实现。&#xff08;1&#xff09;…

Unity Audio Filter 入门

概述&#xff1a; 如果你在你项目中需要一些特殊的声音效果&#xff0c;那这部分声音过滤器的部分一定不要错过喔&#xff0c;让我们来学习这部分的内容吧&#xff01; 这部分理论性比较强&#xff0c;认真看我的注解哈&#xff0c;我尽量解释的易懂一点。 Audio Chorus Filter…

翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习六

合集 ChatGPT 通过图形化的方式来理解 Transformer 架构 翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习一翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习二翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深…

基于Springboot+Vue的Java项目-火车票订票系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

html--剑雨

<!doctype html> <html> <head> <meta charset"utf-8"> <title>css3剑雨-jq22.com</title> <script src"http://www.jq22.com/jquery/jquery-1.10.2.js"></script> <style> .sword:before, .sword:…

Docker基础学习(5.Docker镜像命令)

⭐ 作者简介&#xff1a;码上言 ⭐ 代表教程&#xff1a;Spring Boot vue-element 开发个人博客项目实战教程 ⭐专栏内容&#xff1a;个人博客系统 ⭐我的文档网站&#xff1a;http://xyhwh-nav.cn/ ⭐微信公众号&#xff1a;码上言 文章目录 Docker run流程镜像是什么&a…

云计算技术概述_1.云计算相关概念

1.关于IBM“蓝云&#xff08;Blue Cloud&#xff09;”计划 IBM 推出的“蓝云&#xff08;Blue Cloud&#xff09;”计划为客户带来即可使用的云计算(Cloud Computing)。它包括一系列的云计算产品&#xff0c;使计算不仅仅局限在本地机器或远程Server Farms&#…

树莓派点亮LED灯

简介 使用GPIO Zero library 的 Python库实现点亮LED灯。接线 树莓派引脚参考图如下&#xff1a; LED正极 接GPIO17 LED负极 接GND 权限 将你的用户加到gpio组中&#xff0c; 否则无法控制GPIO sudo usermod -a -G gpio 代码 from gpiozero import LED from time impor…