JSON基础
JSON笔记
一、什么是Json
JSON: JavaScript Object Notation(JavaScript 对象表示法)
JSON 是存储和交换文本信息的语法,类似 XML。
JSON 比 XML 更小、更快,更易解析。
JSON 易于人阅读和编写。
C、Python、C++、Java、PHP、Go等编程语言都支持 JSON。
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。
- JSON 具有自我描述性,更易理解
1 | { |
这个 sites 对象是包含 3 个站点记录(对象)的数组。
与 XML 相同之处
- JSON 是纯文本
- JSON 具有"自我描述性"(人类可读)
- JSON 具有层级结构(值中存在值)
- JSON 可通过 JavaScript 进行解析
- JSON 数据可使用 AJAX 进行传输
与 XML 不同之处
- 没有结束标签
- 更短
- 读写的速度更快
- 能够使用内建的 JavaScript eval() 方法进行解析
- 使用数组
- 不使用保留字
为什么使用 JSON?
对于 AJAX 应用程序来说,JSON 比 XML 更快更易使用:
使用 XML
- 读取 XML 文档
- 使用 XML DOM 来循环遍历文档
- 读取值并存储在变量中
使用 JSON
- 读取 JSON 字符串
- 用 eval() 处理 JSON 字符串
在 AJAX
应用程序中,通常需要从服务器获取数据,并在页面上动态展示。使用 JSON 比
XML 更为方便快捷,因为在使用 JSON 时只需要读取 JSON 字符串并使用
eval()
方法解析即可,而使用 XML 则需要通过 XML DOM
进行文档遍历,读取值并存储在变量中,相对复杂一些。因此,JSON 更适合于在
AJAX 应用程序中进行数据传输和交互。
1 | <!DOCTYPE html> |
这是一个简单的 HTML 页面,通过 JavaScript 创建了一个 JSON 对象,并将该 JSON 对象中的属性值填充到 HTML 页面中的对应元素中。
具体解释如下:
<!DOCTYPE html>
:HTML5 文档声明,指示浏览器采用 HTML5 标准解析页面。
<html>
:HTML 页面的根元素。
<head>
:HTML 文档的头部,包含了页面的元数据和引用的外部资源。
<meta charset="utf-8">
:指定文档使用 UTF-8 字符集编码,确保页面内容能正确显示中文等特殊字符。
<title>菜鸟教程(runoob.com)</title>
:设置页面的标题。
<body>
:HTML 文档的主体部分,包含了页面的可见内容。
<h2>JavaScript 创建 JSON 对象</h2>
:页面标题,用于显示一个二级标题。
<p>
:段落元素,用于包裹文本内容。
<span>
:行内元素,用于包裹文本内容并且可以通过 JavaScript 动态修改其内容。
<script>
:JavaScript 脚本标签,用于在页面中嵌入 JavaScript 代码。
var JSONObject = {...}
:创建一个名为 JSONObject 的 JSON 对象,其中包含了三个属性:name、url、slogan。
document.getElementById("jname").innerHTML = JSONObject.name
:通过 JavaScript 获取 id 为 "jname" 的元素,并将 JSON 对象中的 name 属性值填充到该元素的 innerHTML 属性中,从而显示在页面中。
document.getElementById("jurl").innerHTML = JSONObject.url
:类似地,将 JSON 对象中的 url 属性值填充到 id 为 "jurl" 的元素中。
document.getElementById("jslogan").innerHTML = JSONObject.slogan
:类似地,将 JSON 对象中的 slogan 属性值填充到 id 为 "jslogan" 的元素中。
JSON 语法规则
JSON 语法是 JavaScript 对象表示语法的子集,它具有以下特点:
数据在名称/值对中:每个数据项都包含一个名称和一个对应的值,用冒号
:
分隔。例如:1
2
3
4
5{
"name": "John",
"age": 30,
"city": "New York"
}数据由逗号
,
分隔:在 JSON 中,每个名称/值对之间使用逗号分隔,以便区分不同的数据项。例如:1
2
3
4
5{
"name": "John",
"age": 30,
"city": "New York"
}使用斜杠
\
来转义字符:如果要在 JSON 字符串中表示特殊字符(如双引号),则需要使用反斜杠\
进行转义。例如:1
2
3
4{
"name": "John \"Doe\"",
"age": 30
}大括号
{}
保存对象:JSON 中的对象使用大括号{}
包围,表示一个对象,对象由一组名称/值对组成。例如:1
2
3
4
5{
"name": "John",
"age": 30,
"city": "New York"
}中括号
[]
保存数组:JSON 中的数组使用中括号[]
包围,表示一个有序的值的集合,可以包含多个对象。例如:1
2
3
4
5[
{"name": "John", "age": 30},
{"name": "Jane", "age": 25},
{"name": "Tom", "age": 35}
]
这些特点使得 JSON 成为一种轻量级的数据交换格式,在网络传输和数据存储中被广泛应用。
JSON 的两种结构:
1、对象:
JSON 中的对象是一种无序的名称/值对集合,用大括号 {}
包围。对象由一组名称/值对组成,其中每个名称/值对都由一个键(名称)和一个值组成,键和值之间用冒号
:
分隔,名称/值对之间用逗号 ,
分隔。
举例:
1 | { |
在这个示例中:
"name": "John"
是一个名称/值对,键是"name"
,值是"John"
。"age": 30
是另一个名称/值对,键是"age"
,值是30
。"city": "New York"
是第三个名称/值对,键是"city"
,值是"New York"
。
JSON 对象中的键必须是字符串类型,而值可以是任何有效的 JSON 数据类型,包括字符串、数字、布尔值、数组、对象或 null。
2、数组:
JSON 中的数组是值(value)的有序集合,用中括号 []
包围。数组可以包含零个或多个值,值之间用逗号 ,
分隔。
举例:
1 | [10, 20, 30, 40] |
在这个示例中,数组包含了四个值:10
、20
、30
和
40
。这些值按照它们在数组中出现的顺序排列,并且可以通过索引来访问。
JSON 数组中的值可以是任何有效的 JSON 数据类型,包括字符串、数字、布尔值、对象、数组或 null。
值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array),它们是可以嵌套。
JSON 名称/值对
JSON 数据的书写格式是:
1 | key : value |
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
"name" : "菜鸟教程"
这很容易理解,等价于这条 JavaScript 语句:
name = "菜鸟教程"
JSON 数组
JSON 数组在中括号 [] 中书写:
数组可包含多个对象:
1 | [ |
1 | { |
JSON - 转换为 JavaScript 对象
JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。
由于这种相似性,无需解析器,JavaScript 程序能够使用内建的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象。
JSON 值
JSON 值可以是:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在中括号中)
- 对象(在大括号中)
- null
JSON 数字
JSON 数字可以是整型或者浮点型:
{ "age":30 }
JSON 对象
JSON 数组在中括号 [] 中书写:
数组可包含多个对象:
1 | [ |
1 | { |
在上面的例子中,对象 sites 是包含三个对象的数组。每个对象代表一条关于某个网站(name、url)的记录。
JSON 布尔值
JSON 布尔值可以是 true 或者 false:
1 | { "flag":true } |
JSON null
JSON 可以设置 null 值:
1 | { "runoob":null } |
JSON 使用 JavaScript 语法
- JavaScript 对象数组的定义和访问。
- JavaScript 对象属性的修改。
例子:
1 | javascript复制代码// 定义一个对象数组 sites,包含三个对象,每个对象有 name 和 url 两个属性 |
JSON vs XML
相同点:
- 用于接收 web 服务端的数据。
- 都具有层次结构和自我描述性,易于理解。
- 可被大多数编程语言使用。
不同点:
- 语法:
- JSON 使用 JavaScript
对象表示法,是一种轻量级的数据交换格式,数据存储在名称/值对中,使用大括号
{}
表示对象,而且不需要结束标签。 - XML 使用标记来描述数据,需要使用开始和结束标签包围数据,例如
<tag></tag>
,有时候会显得冗长。
- JSON 使用 JavaScript
对象表示法,是一种轻量级的数据交换格式,数据存储在名称/值对中,使用大括号
- 简洁性和可读性:
- JSON 更加简洁,写法更短,适合数据交换和传输。
- XML 的语法相对冗长,需要大量的标签,相比之下不如 JSON 直观易读。
- 读写速度:
- JSON 的读写速度更快,因为它的结构更加简单直接,不需要额外的解析器来解析。
- XML 读写速度相对较慢,因为它的结构较为复杂,需要使用解析器来解析。
- 支持的数据类型:
- JSON 支持数组,更方便处理列表数据。
- XML 没有直接支持数组的概念,需要使用标签嵌套的方式来表示类似的结构。
- 解析方式:
- JSON 使用标准的 JavaScript 函数来解析,如
JSON.parse()
和JSON.stringify()
。 - XML 需要使用 XML 解析器来解析,较为复杂。
- JSON 使用标准的 JavaScript 函数来解析,如
为什么 JSON 比 XML 更好?
- 简洁性和可读性: JSON 更加简洁、直观,易于理解和编写。
- 读写速度: JSON 的读写速度更快,性能更高。
- 支持的数据类型: JSON 支持数组,更适合表示和处理复杂的数据结构。
- 解析方式: JSON 可以直接使用 JavaScript 对象进行解析,不需要额外的解析器,更加方便和简单。
对象语法
1 | { "name":"runoob", "alexa":10000, "site":null } |
JSON 对象使用在大括号 {...} 中书写。
对象可以包含多个 key/value(键/值)对。
key 必须是字符串,value 可以是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。
key 和 value 中使用冒号 : 分割。
每个 key/value 对使用逗号 , 分割。
访问对象值
你可以使用点号 . 来访问对象的值:
1 | var myObj, x; |
你也可以使用中括号([])来访问对象的值:
1 | var myObj = { "name":"runoob", "alexa":10000, "site":null }; |
循环对象
你可以使用 for-in 来循环对象的属性:
1 | var myObj = { "name":"runoob", "alexa":10000, "site":null }; |
这段代码创建了一个名为
myObj
的 JSON 对象,其中包含了三个属性:name
、alexa
和site
。然后,通过for...in
循环遍历这个 JSON 对象的属性,并将每个属性名添加到 HTML 元素的内容中。具体解释如下:
var myObj = { "name":"runoob", "alexa":10000, "site":null };
:创建了一个名为myObj
的 JSON 对象,其中包含了三个属性:name
、alexa
和site
。属性name
的值是字符串 "runoob",属性alexa
的值是整数 10000,属性site
的值是 null。for (x in myObj) { ... }
:使用for...in
循环遍历myObj
对象的属性。在每次迭代中,x
会依次指向对象的每个属性名。document.getElementById("demo").innerHTML += x + "<br>";
:获取 id 为 "demo" 的 HTML 元素,并将其内容追加为当前迭代的属性名x
,每个属性名之后添加一个换行符<br>
。假设 HTML 中有一个元素如下:
1 <p id="demo"></p>当代码执行时,会将
myObj
对象的属性名逐个添加到 id 为 "demo" 的元素中,结果可能如下:
1
2
3 runoob
10000
null这样,页面中的
demo
元素的内容就会显示 JSON 对象中的属性名。
嵌套 JSON 对象
JSON 对象中可以包含另外一个 JSON 对象:
1 | myObj = { |
你可以使用点号 . 或者中括号 [...] 来访问嵌套的 JSON 对象。
1 | x = myObj.sites.site1; |
修改和删除
1 | myObj = { |
数组作为 JSON 对象
JSON 数组在中括号中书写。
中括号 [] 保存的数组是值(value)的有序集合。一个数组以左中括号 [** 开始, 右中括号 **] 结束,值之间使用逗号 , 分隔。
JSON 中数组值必须是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。
JavaScript 中,数组值可以是以上的 JSON 数据类型,也可以是 JavaScript 的表达式,包括函数,日期,及 undefined。
对象属性的值可以是一个数组:
1
2
3
4
5 {
"name":"网站",
"num":3,
"sites":[ "Google", "Runoob", "Taobao" ]
}索引值获取
1 x = myObj.sites[0];循环遍历
1
2
3 for (i in myObj.sites) {
x += myObj.sites[i] + "<br>";
}
1
2
3 for (i = 0; i < myObj.sites.length; i++) {
x += myObj.sites[i] + "<br>";
}
嵌套 JSON 对象中的数组
JSON 对象中数组可以包含另外一个数组,或者另外一个 JSON 对象:
1 | myObj = { |
1 | for (i in myObj.sites) { |
修改数组值
你可以使用索引值来修改数组值:
1 | myObj.sites[1] = "Github"; |
删除数组元素
我们可以使用 delete 关键字来删除数组元素:
1 | delete myObj.sites[1]; |
JSON.parse() 方法
作用:将 JSON 格式的字符串解析为 JavaScript 对象。
语法:
JSON.parse(text[, reviver])
text
:必需,一个有效的 JSON 字符串。reviver
:可选,一个转换结果的函数,将为对象的每个成员调用此函数。
示例:
1 | // 示例 JSON 字符串 |
- 注意事项:
- 解析前要确保数据是有效的 JSON 格式,否则会出现解析错误。
- JSON 不能直接存储函数,但可以存储函数作为字符串,然后使用
eval()
方法将字符串转换为函数。
从服务端接收 JSON 数据
我们可以使用 AJAX 从服务器请求 JSON 数据,并解析为 JavaScript 对象。
1 | var xmlhttp = new XMLHttpRequest(); |
以上代码是一个使用 AJAX 技术从服务器获取 JSON 数据的示例。
- 创建 XMLHttpRequest 对象:
var xmlhttp = new XMLHttpRequest();
: 创建了一个新的 XMLHttpRequest 对象,用于向服务器发起请求和接收响应。
- 指定响应处理函数:
xmlhttp.onreadystatechange = function() { ... }
: 当 XMLHttpRequest 对象的状态发生改变时,会触发该函数。readyState
属性表示请求的当前状态,status
属性表示响应的 HTTP 状态码。在此示例中,我们只处理状态为4
(完成)且状态码为200
(成功)的响应。
- 发送请求:
xmlhttp.open("GET", "/try/ajax/json_demo.txt", true);
: 使用 GET 方法向服务器发送请求,请求地址为/try/ajax/json_demo.txt
。第三个参数为true
表示异步请求。
- 接收响应:
xmlhttp.send();
: 发送请求到服务器。
- 解析 JSON 数据:
myObj = JSON.parse(this.responseText);
: 当服务器响应就绪时,使用JSON.parse()
方法将服务器返回的 JSON 字符串解析为 JavaScript 对象,并将其赋值给myObj
变量。
- 操作 DOM:
document.getElementById("demo").innerHTML = myObj.name;
: 将解析后的 JavaScript 对象中的name
属性的值显示在 id 为demo
的 HTML 元素中。
从服务端接收数组的 JSON 数据
如果从服务端接收的是数组的 JSON 数据,则 JSON.parse 会将其转换为 JavaScript 数组:
1 | var xmlhttp = new XMLHttpRequest(); |
以上代码是一个使用 AJAX 技术从服务器获取数组形式的 JSON 数据的示例。
- 创建 XMLHttpRequest 对象:
var xmlhttp = new XMLHttpRequest();
: 创建了一个新的 XMLHttpRequest 对象,用于向服务器发起请求和接收响应。- 指定响应处理函数:
xmlhttp.onreadystatechange = function() { ... }
: 当 XMLHttpRequest 对象的状态发生改变时,会触发该函数。readyState
属性表示请求的当前状态,status
属性表示响应的 HTTP 状态码。在此示例中,我们只处理状态为4
(完成)且状态码为200
(成功)的响应。- 发送请求:
xmlhttp.open("GET", "/try/ajax/json_demo_array.txt", true);
: 使用 GET 方法向服务器发送请求,请求地址为/try/ajax/json_demo_array.txt
。第三个参数为true
表示异步请求。- 接收响应:
xmlhttp.send();
: 发送请求到服务器。- 解析 JSON 数据:
myArr = JSON.parse(this.responseText);
: 当服务器响应就绪时,使用JSON.parse()
方法将服务器返回的 JSON 数组字符串解析为 JavaScript 数组,并将其赋值给myArr
变量。- 操作 DOM:
document.getElementById("demo").innerHTML = myArr[1];
: 将解析后的 JavaScript 数组中的第二个元素的值显示在 id 为demo
的 HTML 元素中。
异常
解析数据
JSON 不能存储 Date 对象。
如果你需要存储 Date 对象,需要将其转换为字符串。
之后再将字符串转换为 Date 对象。
1 | var text = '{ "name":"Runoob", "initDate":"2013-12-14", "site":"www.runoob.com"}'; |
以上代码是一个使用 JSON.parse() 方法将 JSON 字符串解析为 JavaScript 对象,并对对象中的日期属性进行处理的示例。
- 定义 JSON 字符串:
var text = '{ "name":"Runoob", "initDate":"2013-12-14", "site":"www.runoob.com"}';
: 定义了一个 JSON 格式的字符串,包含了三个属性:name、initDate 和 site。- 解析 JSON 字符串:
var obj = JSON.parse(text);
: 使用 JSON.parse() 方法将 JSON 字符串 text 解析为 JavaScript 对象,并将其赋值给 obj 变量。解析后的对象包含了 name、initDate 和 site 三个属性,其中 initDate 的值仍然是一个字符串。- 处理日期属性:
obj.initDate = new Date(obj.initDate);
: 将 initDate 属性的值转换为 Date 对象,以便在后续的操作中能够以日期的形式进行处理。- 操作 DOM:
document.getElementById("demo").innerHTML = obj.name + "创建日期: " + obj.initDate;
: 将解析后的对象中的 name 属性值和转换后的 initDate 属性值显示在 id 为 "demo" 的 HTML 元素中。在输出 initDate 时,它会自动转换为日期格式。
我们可以启用 JSON.parse 的第二个参数 reviver,一个转换结果的函数,对象的每个成员调用此函数。
1 | var text = '{ "name":"Runoob", "initDate":"2013-12-14", "site":"www.runoob.com"}'; |
- 定义 JSON 字符串:
var text = '{ "name":"Runoob", "initDate":"2013-12-14", "site":"www.runoob.com"}';
: 定义了一个 JSON 格式的字符串,包含了三个属性:name、initDate 和 site。- 使用 JSON.parse() 方法解析 JSON 字符串:
var obj = JSON.parse(text, function (key, value) {...});
: 调用 JSON.parse() 方法,第一个参数是待解析的 JSON 字符串,第二个参数是一个函数,称为 reviver 函数。在解析过程中,reviver 函数会对解析出的每个键值对进行处理,根据键名 key 和键值 value 返回一个新值。- reviver 函数的定义:
function (key, value) { ... }
: 定义了一个 reviver 函数,该函数接受两个参数:key 表示当前解析的键名,value 表示当前解析的键值。在该函数中,通过判断键名是否为 "initDate",如果是,则将对应的值转换为 Date 对象;否则,直接返回原始值。- 处理日期属性:
if (key == "initDate") { return new Date(value); } else { return value; }
: 在 reviver 函数中,判断当前解析的键名是否为 "initDate",如果是,则将对应的值 value 转换为 Date 对象;否则,直接返回原始值 value。- 操作 DOM:
document.getElementById("demo").innerHTML = obj.name + "创建日期:" + obj.initDate;
: 将解析后的对象中的 name 属性值和经过 reviver 处理后的 initDate 属性值显示在 id 为 "demo" 的 HTML 元素中。
解析函数
1 | var text = '{ "name":"Runoob", "alexa":"function () {return 10000;}", "site":"www.runoob.com"}'; |
以上代码是一个使用 JSON.parse() 方法解析 JSON 字符串的示例,其中包含了一个属性值为函数的情况,并使用 eval() 方法将其转换为可执行的 JavaScript 函数。
- 定义 JSON 字符串:
var text = '{ "name":"Runoob", "alexa":"function () {return 10000;}", "site":"www.runoob.com"}';
: 定义了一个 JSON 格式的字符串,包含了三个属性:name、alexa 和 site。其中,alexa 的值为一个函数的字符串表示。- 使用 JSON.parse() 方法解析 JSON 字符串:
var obj = JSON.parse(text);
: 调用 JSON.parse() 方法,将 JSON 字符串解析为 JavaScript 对象。- 处理函数属性:
obj.alexa = eval("(" + obj.alexa + ")");
: 将属性名为 alexa 的值从字符串表示的函数转换为 JavaScript 可执行的函数对象。这里使用了 eval() 方法来执行字符串表达式,将字符串转换为函数对象。- 执行函数:
obj.alexa()
: 调用对象的 alexa 属性,实际上是调用了被转换后的函数对象。由于该函数是一个返回固定值的函数,因此执行后会返回固定的 Alexa 排名值。- 操作 DOM:
document.getElementById("demo").innerHTML = obj.name + " Alexa 排名:" + obj.alexa();
: 将解析后的对象中的 name 属性值和经过 eval() 处理后的 alexa 属性值显示在 id 为 "demo" 的 HTML 元素中,展示了 Alexa 排名。
JSON.stringify()
JSON.stringify()
方法用于将 JavaScript 值转换为 JSON
字符串。这个方法接受一个 JavaScript
值(通常是一个对象或数组),并返回对应的 JSON 字符串。
语法
1 | JSON.stringify(value[, replacer[, space]]) |
value
: 必需,要转换为 JSON 字符串的值。replacer
: 可选,用于转换结果的函数或数组,用于选择性地过滤和转换结果。如果是一个函数,将为对象的每个成员调用该函数。如果是数组,只有包含在数组中的属性名才会被转换。space
: 可选,用于增加输出的可读性,如果是一个数字,则表示每一级别的缩进空格数。
例子
1 | var obj = { |
输出结果为:
1 | {"name":"John","age":30,"city":"New York"} |
注意事项
JSON.stringify()
方法会忽略对象的不可枚举属性。- 如果对象的某个属性值为
undefined
、function
或symbol
类型,则在 JSON 字符串中会被省略(或者在使用函数形式的replacer
参数时返回null
)。 - 如果数组的某个元素的值为
undefined
、function
或symbol
类型,则在 JSON 字符串中会被转换为null
。 - 在处理循环引用对象时,
JSON.stringify()
会抛出TypeError
错误。
把 JSON 文本转换为 JavaScript 对象
要将 JSON 文本转换为 JavaScript 对象,可以使用
JSON.parse()
方法,这是一个更安全且性能更高的选项。
例子:
假设有以下 JSON 文本字符串:
1 | var txt = '{ "sites" : [' + |
可以使用 JSON.parse()
将其转换为 JavaScript 对象:
1 | var obj = JSON.parse(txt); |
在网页中使用 JavaScript 对象:
假设我们想在网页中显示第一个站点的名称和 URL,可以这样做:
1 |
|
注意事项:
- 使用
JSON.parse()
进行解析是更安全和更高效的选择,因为它只会解析 JSON 文本,而不会编译执行 JavaScript 代码。 - 避免使用
eval()
函数来解析 JSON 文本,因为它会执行任何 JavaScript 代码,存在安全风险。 - 大多数现代浏览器和 ECMAScript 标准都原生支持
JSON.parse()
,因此推荐使用它来解析 JSON 文本。
示例:
服务端(Node.js)
假设我们有一个 Node.js 服务器,它提供了一个 API 来获取用户信息。我们将用户信息存储在一个 JSON 文件中。
users.json
1 | { |
server.js
1 | const http = require('http'); |
这段代码创建了一个简单的 Node.js 服务器,它监听指定的端口(默认为 3000)。当客户端发送 GET 请求到
/api/users
路径时,服务器会读取名为users.json
的文件,并将其内容作为 JSON 格式的响应返回给客户端。如果请求的路径不是/api/users
,服务器将返回 404 错误。让我们逐行解释这段代码:
const http = require('http');
和const fs = require('fs');
:导入 Node.js 内置的http
和fs
模块,分别用于创建 HTTP 服务器和读取文件。
const server = http.createServer((req, res) => { ... });
:创建一个 HTTP 服务器实例,传入一个回调函数作为参数。这个回调函数会在每次接收到 HTTP 请求时被调用。回调函数接收两个参数:req
表示客户端的请求信息,res
表示服务器端的响应信息。
if (req.url === '/api/users' && req.method === 'GET') { ... } else { ... }
:判断客户端发送的请求路径是否为/api/users
,并且请求方法是否为 GET。如果是,执行对应的逻辑;否则返回 404 错误。
fs.readFile('users.json', 'utf8', (err, data) => { ... });
:使用fs.readFile
方法读取名为users.json
的文件,第一个参数是文件路径,第二个参数是编码格式,第三个参数是一个回调函数,用于处理读取文件的结果。如果读取成功,回调函数的data
参数将包含文件内容;如果读取失败,err
参数将包含错误信息。
res.writeHead(500, { 'Content-Type': 'application/json' });
和res.end(JSON.stringify({ error: 'Internal Server Error' }));
:如果读取文件失败,服务器将返回 500 错误,并将错误信息以 JSON 格式返回给客户端。
res.writeHead(200, { 'Content-Type': 'application/json' });
和res.end(data);
:如果读取文件成功,服务器将返回 200 成功响应,并将文件内容以 JSON 格式返回给客户端。
const PORT = process.env.PORT || 3000;
:定义服务器监听的端口号,可以从环境变量中获取,如果没有设置则默认为 3000。
server.listen(PORT, () => { console.log(
Server is running on port ${PORT}); });
:启动服务器,监听指定的端口。启动成功后,在控制台打印服务器运行的端口号。
客户端(HTML + JavaScript)
index.html
1 |
|
这段 HTML 文件是一个简单的用户列表页面,通过 AJAX 请求从服务器端获取用户数据,并将数据显示在页面上。
让我们逐行解释这段代码:
<!DOCTYPE html>
:声明文档类型为 HTML5。
<html lang="en">
:HTML 根元素,指定页面语言为英语。
<head>
:头部标签,包含了页面的元信息,如字符编码、视口设置和标题。
<meta charset="UTF-8">
:指定文档字符集为 UTF-8,支持显示各种字符。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
:设置视口宽度为设备宽度,并且初始缩放为 1.0,确保页面在移动设备上显示正确。
<title>JSON 数据通信示例</title>
:设置页面标题为 "JSON 数据通信示例"。
<body>
:页面主体部分。
<h1>User List</h1>
:页面标题,显示为 "User List"。
<ul id="user-list"></ul>
:空的无序列表,用于显示用户列表。
<script>
:JavaScript 脚本标签,用于处理页面逻辑。
const xhr = new XMLHttpRequest();
:创建 XMLHttpRequest 对象,用于发送 HTTP 请求。
xhr.onreadystatechange = function() { ... }
:定义了一个回调函数,用于处理 AJAX 请求的状态变化。
xhr.readyState === XMLHttpRequest.DONE
:当请求状态为 DONE 时,表示请求完成。
xhr.status === 200
:当响应状态码为 200 时,表示请求成功。
const users = JSON.parse(xhr.responseText).users;
:解析服务器返回的 JSON 数据,并提取其中的用户数组。
const userListElement = document.getElementById('user-list');
:获取页面上的用户列表元素。
users.forEach(user => { ... });
:遍历用户数组,对每个用户创建一个列表项,并添加到用户列表中。
xhr.open('GET', '/api/users');
:配置请求,指定请求方法为 GET,请求地址为/api/users
。
xhr.send();
:发送请求到服务器。这段代码的主要作用是从服务器端获取用户数据,然后将数据动态地显示在页面上的用户列表中。
运行示例
- 确保你的机器上已安装了 Node.js。
- 在项目目录下创建
users.json
和server.js
文件,并填入相应的内容。 - 打开终端,进入到项目目录,运行
node server.js
启动 Node.js 服务器。 - 在浏览器中打开
index.html
文件,你应该能看到用户列表信息。
这个示例演示了一个简单的服务端和客户端的应用,其中服务端提供了一个 API 来获取用户信息,并将其以 JSON 格式返回给客户端。客户端使用 AJAX 技术向服务端发送请求,并处理返回的 JSON 数据以显示用户列表。