JSON教程(非常详细)

news/2024/5/17 16:57:38

参考文章来源: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.mrgr.cn/p/18522106

相关文章

高效遍历:C++中分隔字符串单词的3种方法详解与实例

概述:在C++中,遍历由空格分隔的字符串的单词有多种方法,包括使用`std::istringstream`、手动遍历字符和正则表达式。其中,`std::istringstream`是简单高效的选择,通过流提取单词。手动遍历字符较为繁琐,正则表达式方法更灵活但可能有性能开销。根据实际需求选择方法,本文…

深度学习:基于Keras,使用长短期记忆人工神经网络模型(LSTM)对股票市场进行预测分析

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

【如何使用SSH密钥验证提升服务器安全性及操作效率】(优雅的连接到自己的linux服务器)

文章目录 一、理论基础&#xff08;不喜欢这部分的可直接看具体操作&#xff09;1.为什么要看本文&#xff08;为了zhuangbility&#xff09;2.为什么要用密钥验证&#xff08;更安全不易被攻破&#xff09;3.密码验证与密钥验证的区别 二、具体操作1.生成密钥对1.1抉择&#x…

Hydro OJ搭建全过程

第一步 : 注册服务器 如果你和我一样,是一名新手党,想先免费调试自己的站点,那我教你免费申请一个服务器。 在这里安利一下阿贝云,一个免费的云服务器和免费的云虚拟主机提供方,对于新手党来说确实不错。 注册完一个账户以后,你需要支付0.3元做一个实名认证,如果实名认证…

VULHUB复现log4j反序列化漏洞-CVE-2021-44228

本地下载vulhub复现就完了&#xff0c;环境搭建不讲&#xff0c;网上其他文章很好。 访问该环境&#xff1a; POC 构造&#xff08;任选其一&#xff09;&#xff1a; ${jndi:ldap://${sys:java.version}.xxx.dnslog.cn} ${jndi:rmi://${sys:java.version}.xxx.dnslog.cn}我是…

读天才与算法:人脑与AI的数学思维笔记16_音乐图灵测试

读天才与算法:人脑与AI的数学思维笔记16_音乐图灵测试1. 艾米 1.1. 人工智能作曲家 1.1.1. 分析机可能会生成任意复杂程度、精细程度的科学的音乐作品 1.1.1.1. 阿达洛夫莱斯 1.1.2. 巴赫的作品是大多数作曲家开始学习创作的起点…

Node.js -- MongoDB

文章目录 1. 相关介绍2. 核心概念3. 命令行交互3.1数据库命令3.2 集合命令3.3 文档命令 4. 数据库应用场景4.1 新增4.2 删除4.3 更新4.4 查询 5. 图形化工具Robo 3T 1. 相关介绍 一、简介 Mongodb是什么 MongoDB是一个基于分布式文件存储的数据库&#xff0c;官方地址https://…

c3 笔记6 认识css样式表

<link>与import应该如何选择?事实上&#xff0c;使用link与import链接外部样式文件的效果看起来是一样的&#xff0c;区别在于<link>是HTML标记而import属于CSS语法。<link>标记有rel、type与href属性&#xff0c;可以指定CSS样式表的名称&#xff0c;这样就…

电影交流|基于SprinBoot+vue的电影交流平台小程序系统(源码+数据库+文档)

电影交流平台目录 目录 基于SprinBootvue的电影交流平台小程序系统 一、前言 二、系统设计 三、系统功能设计 1用户信息管理 2 电影信息管理 3公告信息管理 4论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取…

【跟马少平老师学AI】-【神经网络是怎么实现的】(九)长短期记忆网络

一句话归纳&#xff1a; 1&#xff09;RNN也会存在梯度消失的问题。 2&#xff09;同一句话&#xff0c;对于不同的任务&#xff0c;句中不同的词起的作用也不一样。 3&#xff09;LSTM&#xff08;长短期记忆&#xff09;子网络&#xff1a; 门&#xff0c;让输入经过运算&…

经营贷的风险及老百姓当下不要碰这玩意

一、经营贷的基本概念和发展历程 首先,我们要知道什么是经营贷? 这里我们所讨论的“经营贷”全称为房产抵押经营贷,是指借款人以自己名下的房产作为抵押物,向银行或其他金融机构申请的用于企业经营活动的贷款产品。这类贷款的主要目的是为小微企业主或个体工商户提供流动资…

四信数字孪生水库解决方案,加快构建现代化水库运行管理矩阵

近年&#xff0c;水利部先后出台《关于加快构建现代化水库运行管理矩阵的指导意见》与《构建现代化水库运行管理矩阵先行先试工作方案》等文件&#xff0c;明确总体要求及试点水库、先行区域建设技术要求等&#xff0c;为全面推进现代化水库运行管理矩阵建设工作提供依据。 《2…

云原生Kubernetes: K8S 1.29版本 部署Harbor

目录 一、实验 1.环境 2.Linux 部署docker compose 3.证书秘钥配置 4.K8S 1.29版本 部署Harbor 5.K8S 1.29版本 使用Harbor 二、问题 1.docker 登录harbor失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构版本IP备注masterK8S master节点1.2…

【保姆级教程】用IDEA2023版本给RuoYi-Vue添加子模块

文章目录 前言添加子模块新建子模块新建子模块界面&#xff1f;新建子模块界面&#xff01; 修改pom依赖配置RuoYiApplication添加测试接口配置接口权限测试 前言 若依前后端分离框架能够极大方便当前开发任务&#xff0c;并且使用的技术栈也相当丰富&#xff0c;但是目前只提…

Unity SteamVR入门

概述 VR项目现在在当前已经是非常热门的技术&#xff0c;可以给玩家身临其境的感觉&#xff0c;接下来让我们学习这部分的内容吧&#xff01; SteamVR Input SteamVR绑定流程&#xff0c;在Windows窗口的点击SteamVR-input&#xff0c;图1&#xff0c;在这里可以选择你需要绑定…

Themis新篇章:老牌衍生品协议登陆Blast L2,探索全新经济模型

本文将深入分析 Themis 的最新经济模型&#xff0c;探讨其核心概念和机制、优势与创新之处、风险与挑战。 一、引言 随着区块链技术的不断发展&#xff0c;DeFi 衍生品项目逐渐成为市场的焦点。而用户体验的革新&#xff0c;进一步的金融创新&#xff0c;去中心化治理方案的优…

C语言/数据结构——每日一题(反转链表)

一.前言 大家好&#xff01;今天又是每日一题环节。今天我为大家分享了一道单链表题——反转链表。 废话不多说&#xff0c;让我们直接进入正题吧。 二.正文 1.1题目信息 这是一道leetCode上面的一道题&#xff1a;https://leetcode.cn/problems/reverse-linked-list 1.2解…

2024-05-02 通达信指标 大盘涨跌家数

X_1:="999999$ADVANCE";X_2:="999999$DECLINE";X_3:="399107$ADVANCE";X_4:="399107$DECLINE";总家数:X_1+X_2+X_3+X_4+"880005$LOW",NODRAW;涨家数:X_1+X_3,NODRAW;跌家数:X_2+X_4,NODRAW;差数:涨家数-跌家数,NODRAW;涨占比…

2024-05-01 通达信指标 获利比例

平均成本线:COST(50),COLORYELLOW,NODRAW;三十周成本:LWINNER(150,C)COLORYELLOW;获利比例:WINNER(C)*100,COLORGREEN; DRAWLINE(O,90,O,90,1),COLORWHITE;DRAWLINE(O,70,O,70,1),COLORWHITE;

量子城域网建设设备系列(二):量子密钥管系统(KMS)

在上文介绍光量子交换机的文章中我们提到&#xff0c;量子保密通信网络的通道切换是由量子密钥管理系统&#xff08;Key Management System&#xff0c;KMS&#xff09;给光量子交换机下发信道切换指令&#xff0c;实现整个网络中任意两对量子密钥分发终端的量子信道互联互通&a…