AJAX 的原理与应用
AJAX的全称: Asynchronous JavaScript And XML
- 测试代码地址
- 请求接口测试代码地址
- 黑马免费教学接口API:
http://www.liulongbin.top:3006/api
大纲链接 §
[toc]
0. 服务器的基本概念与初识Ajax ⇧
- 客户端和服务器
- 客户端和服务器基本概念
- 客户端和服务器通信过程
- URL地址
- 网页打开的过程
- 服务器对外提供的资源包括图片以及数据
- Ajax概念和应用场景
- 使用 Axios 代替过时的jQuery发起Ajax请求数据
- 接口和接口文档
- 过时的form表单与模板引擎
- 案例
- 图书管理接口
- 案例-聊天机器人接口
上网的目的:通过互联网的形式来获取和消费网络资源
0.1 客户端和服务器 ⇧
- 客户端和服务器基本概念:
- 上网过程中,负责存放和对外提供资源的计算机,叫服务器
- 上网过程中,负责获取和消费资源的计算机,叫客户端
- 客户端和服务器通信过程
0.2 URL地址 ⇧
- 统一资源定位符,同于标识互联网上每个资源的唯一存放位置(不可重复)
- 客户端只有通过URL地址,才能正确定位的存放位置,从而成功访问到对应的资源
URL地址一般有三部分组成
- 客户端与服务器的通信协议,
https等,在://之前 - 存有该资源的服务器名称,
www.xxx.com - 资源在服务器上的具体存放路径
0.3 网页打开的过程 ⇧
- 即客户端和服务器通信过程,分为:请求->处理->响应
- 在浏览器的地址栏输入网站地址,回车,向服务器发起资源请求
- 服务器处理这次资源请求
- 服务器将这次请求的响应发送给客户端
- 响应可以是成功或者拒绝
浏览器Network面板简介
- 资源筛选页签
- XHR 表示数据请求对象
XMLHttpRequest,有的浏览器显示为Fetch/XHR - Doc 表示文档资源,有的浏览器显示为
HTML
- XHR 表示数据请求对象
- Headers 页签
Request URLRequest MethodStatus CodeRemote AddressReferrer Policy
Response表示服务器的响应数据,格式为对应数据的格式
0.4 服务器对外提供的资源 ⇧
- 文字
- 脚本
- 样式
- 图片
- 音频
- 视频
- 数据
网页中的数据也是服务器对外提供的一种资源
- 网页中 HTML控制骨架、CSS控制样式、JS控制逻辑交互行为、数据则提供主要信息,骨架、样式和交互都为数据服务
- 常见的数据传输格式有
JSON、XML(前端不常用)
0.5 网页中如何请求数据 ⇧
数据也是服务器对外提供的一种资源,只要是资源,必然通过 请求 -> 响应 -> 的方式获取
- 如果要在网页中请求服务器上的数据资源,则需要用到
XMLHttpRequest对象 XMLHttpRequest对象简称xhr,是浏览器提供给JS内建的浏览器对象,属于BOM- 通过
new XMLHttpRequest()方法构造实例对象,可以请求服务器上的数据资源 const xhr = new XMLHttpRequest()
0.6 资源的请求方式(请求动词) ⇧
客户端请求服务器时,请求的方式有很多种,最常见的两种方式分别为
get和post请求
get请求用于获取服务端资源- 根据 URL 地址,从服务器获取 HTML、CSS、JS、图片和数据等文件资源
post请求用于向服务器提交数据,即发送资源- 例如:登录时向服务器提交的登录消息、注册时向服务器提交的注册信息、添加用户时向服务器提交的用户数据信息等给中数据提交操作
0.6 Ajax概念和应用场景 ⇧
- 在网页中利用 XMLHttpRequest 对象和服务器进行数据交互的方式就是 Ajax
- 页面可以无刷新的请求数据
- Ajax 能实现静态网页无法实现的和服务器之间数据交互功能
- 用户通过和网页或应用这一数据载体交互,实现和服务器进行数据交互
- 代替过时的 form 表单默认提交(页面强制刷新)和 jQuery 发起 Ajax 请求数据
- 使用 Fetch API
- 使用 Axios
Ajax的典型应用场景
- 用户名的检测:注册用户时,通过 Ajax 的形式,动态检测用户名是否被占用,名称查重
- 搜索提示:当输入关键字时,通过 Ajax 的形式,动态加载搜索提示列表
- 数据分页显示:点击页码时,通过 Ajax 的形式,根据页码值动态刷新该页页面数据
- 数据增删改查,实现数据的交互
在现代浏览器上实现一个Ajax请求
|
|
0.7 代替过时的jQuery发起Ajax请求数据 ⇧
- 使用黑马的免费教学接口API:
http://www.liulongbin.top:3006/api
jQuery
|
|
Axios ⇧
- 易用、简洁且高效的http库
- 支持node端和浏览器端
- 基于 Promise 管理异步,是对原生XHR的封装,用Promise的实现版本,符合最新的ES规范
- 支持HTTP拦截器等高级配置,拦截请求和响应
- 取消请求
- 自动转换 JSON 数据,转换请求数据和响应数据
- 响应超时
- 同时请求
- 客户端支持防御 XSRF
安装
|
|
引入
|
|
基本用法
axios.get(url[, config])- 代替 jQuery 的
$.get(url: string, [data: object /*请求参数*/], [callback: function /*成功回调*/])
- 代替 jQuery 的
axios.post(url[, data[, config]])- 代替 jQuery 的
$.post(url: string, [data: object /*要提交的数据*/], [callback: function /*数据提交成功回调*/])
- 代替 jQuery 的
axios({...})代替 jQuery 的$.ajax()- 为其他支持的请求方法提供的别名
axios.request(config)axios.delete(url[, config])axios.head(url[, config])axios.options(url[, config])axios.put(url[, data[, config]])axios.patch(url[, data[, config]])- 在使用别名方法时, url、method、data 这些属性都不必在配置中指定
axios-get.js,语法:axios.get(url[, config])
|
|
成功返回的数据
1 2 3 4 5 6 7 8 9{ "status": 200, "msg": "获取图书列表成功", "data": [ { "id": 1, "bookname": "西游记", "author": "吴承恩", "publisher": "北京图书出版社"}, { "id": 2, "bookname": "三国演义", "author": "罗贯中", "publisher": "重庆图书出版社"}, { "id": 3, "bookname": "红楼梦", "author": "曹雪芹", "publisher": "上海图书出版社"} ] }
使用 APIFox 配置好接口 直接生成代码,以
Fetch API为例
|
|
- node-fetch/node-fetch github
- 在浏览器的network面板中查看所有 Ajax 请求,点击 Fetch/XHR 过滤 Ajax 请求
axios-post.js,语法:axios.post(url[, data[, config]])
|
|
axios-axios.js,语法:axios(config: object)
|
|
0.8 接口和接口文档 ⇧
使用 Ajax 请求数据时,被请求的 URL 地址,就叫做后端数据接口(简称接口),同时,每个接口必须有请求方式,例如:
GET请求http://www.liulongbin.top:3006/api/getbooks获取图书列表的接口POST请求http://www.liulongbin.top:3006/api/addbook添加图书的接口
分析接口的请求过程
GET请求过程:用户希望获取数据 -> 浏览器网页(数据载体)通过 Ajax 发起 GET 数据请求 -> 服务器 处理请求 -> 服务器发送响应给 浏览器 Ajax -> 浏览器网页展现结果POST请求过程:用户希望提交数据 -> 浏览器网页(数据载体)通过 Ajax 发起 POST 数据请求 -> 服务器 处理请求 -> 服务器发送响应给 浏览器 Ajax -> 浏览器网页展现结果
接口测试工具
- 为了验证接口能否被正常访问,常常需要使用接口测试工具,来对后端数据接口进行检测
- 接口测试工具能在不写任何代码的情况下,对接口进行调用和测试
- 一般有如下几种方式
- 命令行
curl - IDE比如WebStorm自带的 工具 > HTTP客户端
- 国外 Postman
- 国内 apifox 和 apipost
- 命令行
使用 Postman 和 apifox 和 apipost
- Apifox 使用文档
- Postman 添加标签 Tab
- 选择 请求类型
- 填写 URL地址
- 在请求参数区域,填写参数和数据
- GET 需要在 Params 中填写
- POST 主要在
Body中填写- 一般点选
x-www-form-urlencoded后填写
- 一般点选
- 发送请求按钮 Send
- 查看服务器响应结果
使用 rap2 接口平台
- 可以自动生成文档,导入导出给中格式文档数据
0.9 案例,以vue为例 ⇧
- 案例
- 图书管理接口(Vue + Axios)
- 聊天机器人接口
0.9.1 图书管理接口(Vue + Axios) ⇧
BooksInfo.vue页面组件
|
|
实现
AddBookInfo.vue
|
|
实现
ShowBookInfo.vue
|
|
实现
addbook.ts
|
|
实现
delBook.ts
|
|
实现
getBookList.ts
|
|
0.9.2 聊天机器人接口 ⇧
头铁聊天AI机器人
- 文字
http://www.liulongbin.top:3006/api/robot?spoken= - 语音
http://www.liulongbin.top:3006/api/synthesize?text=
0.10 form表单的现代用法 ⇧
<form></form>表单的常用属性- 通过 Ajax 提交表单数据
- 阻止表单的默认提交行为
- 案例 评论列表
- 快速获取表单的数据
- 使用表单库
formily
表单在网页中主要负责 数据采集 的功能,即用于采集用户输入的信息,并通过
<form>标签的提交操作,将采集的信息提交对服务端进行处理
|
|
- 表单由三个基本部分组成:
- 表单标签
<form></form> - 表单域可以包含以下常用元素:
- 文本框
- 密码框
- 隐藏域
- 多行文本框
- 复选框
- 单选框
- 下拉选择框
- 表单按钮
<button type="submit"></button>
- 表单标签
0.10.1 表单标签的属性
<form></form>标签用来采集数据,<form></form>标签的属性则是用来规定 如何将采集到的数据发送到服务器
| 属性 | 值 | 描述 |
|---|---|---|
action |
URL地址 | 规定当提交表单时,向何处发送表单数据 |
method |
GET(/POST) | 规定以何种方式将表单数据提交到 action URL |
enctype |
*1 默认application/x-www-form-urluncoded |
规定在发送表单数据之前,如何对其进行编码的格式 |
target |
*2 默认_self |
规定在浏览器何处打开 action URL |
*1编码格式有:application/x-www-form-urluncodedmultipart/form-datatext/plain
*2打开方式有:_blank_self_parent_topframename
action
action规定当提交表单时,向何处发送表单数据action属性的值应该是 后端提供的 一个 URL 地址,这个 URL 地址专门负责接受表单提交过来的数据(即表单的数据最终提交到action属性所指向的 URL 地址来进行处理)- 当
<form></form>表单在未指定action属性值得情况下,action的默认值为当前页面的 URL 地址 - 当提交表单后,页面会立即跳转到
action属性指定的 URL 地址,同时将表单的数据以查询参数字符传的形式放在 URL 后
target
- 和
<a></a>标签的属性相同,规定在浏览器何处打开action URL - 可选值有5个,默认情况下,
target的值为_self,表示在相同的框架或窗口中打开,一般为在当前页面中打开action URL
| 值 | 描述 |
|---|---|
_blank |
在新标签页打开 |
_self |
默认值,在相同的框架或窗口中打开 |
_parent |
在父框架集中打开(很少用) |
_top |
在整个窗口中打开(很少用) |
framename |
在指定的框架中打开(很少用) |
method
- 规定以何种方式将表单数据提交到
action URL - 可选值只有两个,分别是
GET和POST,不支持其他方式(请求动词)- 大小写不敏感
- 默认情况下,
method的值为GET,表示通过 URL 的形式,把表单数据提交到action URL- 数据为以
?开头,数据名=数据值的形式,并以&连接不同的数据,一般称为查询字符串参数Query String Parameters
- 数据为以
- 发出
POST请求时,提交的数据并不会显示在地址栏 URL 中
发出请求后,查看浏览器
Network面板中请求相关信息
- 请求地址
Request URL完整地址 - 发出
GET请求时,查询字符串参数Query String Parameters被单独取出,并分别显示数据 - 发出
POST请求时,Request URL只包含action URL- 数据是通过
Form Data的形式提交 - 数据相对更隐蔽,但不使用
https协议的话,仍为明文传输数据,不安全
- 数据是通过
注意
GET的语义为获取数据,提交的数据为查询参数,目的为查询并获取服务器上的数据,在表单中较少使用POST的语义为提交数据,适合用来在表单提交数据给服务器,包括文件上传- 登录。注册或添加数据等表单操作,都只使用
POST方式来提交表单
- 登录。注册或添加数据等表单操作,都只使用
enctype
- 规定在发送表单数据之前,如何对其进行 编码的格式
- 可选值有三个,默认值为
application/x-www.form-urlencoded,表示在发送前编码所有的字符
| 值 | 描述 |
|---|---|
application/x-www.form-urlencoded |
默认值,表示在发送前编码所有的字符,一般字符串数据 |
mutipart/form-data |
表示不对字符编码,在使用包含 文件上传空间的表单 时,必须使用该值 |
text/plain |
三空格转换为 + 号,但不对特殊字符编码,极少用 |
表单提交注意
- 在涉及 文件上传 操作时,必须将
enctype的值设置为mutipart/form-data - 不涉及 文件上传 操作时,则将
enctype的值设置为application/x-www.form-urlencoded
0.10.2 表单的同步提交及缺点
- 通过
submit按钮,触发表单提交的操作,从而使页面跳转到action URL的行为,叫做表单的同步提交
表单同步提交的缺点
<form></form>表单同步提交后,整个页面会发生跳转,跳转到action URL所指向的地址,用户体验相对不好<form></form>表单同步提交后,回退到页面之前的状态和填写的数据会丢失
0.10.3 通过 Ajax 提交表单
可以解决表单同步提交的两个缺点
- 页面发生跳转
- 页面状态和数据丢失
表单 只负责采集数据,
Ajax负责将数据提交到服务器
- 监听表单的提交事件
submit - 阻止表单默认提交行为
event.preventDefault() - 快速获取表单中的数据
- 使用 Ajax 异步提交数据
监听表单的提交事件 submit
- 当表单提交的时候触发submit事件
- 注意submit事件只能作用于
form元素中,不能单独作用于button或者<input type="submit">,查看MDN -> submitonsubmit
阻止表单默认提交行为
即阻止默认表单提交后的跳转行为
- 当监听到表单的提交事件后,可以在回调函数中调用事件对象
e的e.preventDefault()函数,来阻止表单的提交和页面的跳转
0.10.4 获取表单中的数据
在发送请求之前,需要获取用户填写表单的数据
- 在获取表单数据时,必须为每个表单域中需要获取数据的元素添加
name属性,而且值不能重复 - 封装类似于JQ中的
serialize(),将表单所有输入框的信息,按照name= 用户填写的value,以及连接符&,进行拼接 - jQuery序列化表单数据 serialize()、serializeArray()及使用
参考
- Formily–阿里统一表单解决方案 知乎
- 如何评价Formily2.0? 知乎
- Formily教程 | formily是中后台复杂场景的表单解决方案
- Formily实践
- alibaba/formily github
- Alibaba Formily 中文官网
1. AJAX原理和应用 § ⇧
1.1 AJAX是浏览器上的功能 ⇧
- 通过JS发请求和收响应实现前后端交互
- 浏览器可以发请求,收响应
- 浏览器在
window上加一个XMLHttpRequest构造函数 XMLHttpRequest属于 BOM 浏览器模型 * MDNXMLHttpRequest对象实例可以发出HTTP请求与接收HTTP响应- 使用浏览器内置的
XMLHttpRequest和fetch API(ES6), 实现在页面不刷新的情况下和服务端进行数据交互 - 优点:交互数据时不需要刷新整个页面,只需局部刷新,页面不发生用跳转
- 一旦拿到服务器返回的数据,AJAX 不会刷新整个网页,而是只更新网页里面的相关部分,从而不打断用户正在做的事情,体验较好
- 注意,AJAX 只能向 同源网址 (协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错
支持所有 HTTP 请求方法(请求动词)
1 2typeof window.XMLHttpRequest // function用这个构造函数(类)可以构造出一个对象
JS通过它实现发请求,收响应
1.2 准备服务器 ⇧
- 使用 server.js 作为服务器
- 下载或复制代码即可用
node sever.js 8888启动 使用
node-dev工具 ,安装1 2 3 4yarn global add node-dev # 或者用 npm install -g node-dev用
node-dev代替node,实现自动重启服务器但不能监听页面自动刷新
1node-dev server.js 8888添加
index.html / main.js两个路由路由就是
if..else在
index.html中加载路由读取的main.js加载的文件中引用到的路径,必须和路由的
if..else中的路径path一致,server.js才会加载而
response.write(fs.readFileSync('src/xxx'))中的是相对路径,和path的不同
1.3 复习 ⇧
- 在
server.js中添加路由(条件),访问文件 - 添加
response.statusCode = 200 - 设置
Content-Type为对应的类型response.setHeader('Content-Type', 'text/javascript;charset=utf-8') - 把文件读成字符串,再传入
response.write 结束,关闭
response.end()1 2const string = fs.readFileSync('src/index.html') response.write(string)
文件实际上对于
node服务器来说就是字符串,只不过把字符串写到文件里而已
【HTTP非全解】请求和响应 & Node.Js Server
1.4 如何使用JS原生XMLHttpRequest发起 Ajax 请求 ⇧
1.4.1 XMLHttpRequest的基本使用 ⇧
XMLHttpRequest(简称xhr)时浏览器提供的JS内置对象,通过它,可以 请求服务器上的数据源- JQ中的
.ajax函数和axios是库基于xhr对象封装
- JQ中的
- 和它同一等级的底层接口,功能相同的ES6 API是
Fetch API
以发送GET请求为例:
- 创建对象
new XMLHttpRequest()一般使用命名为 xhr 的变量接收 - 配置参数
.open('GET', url)指定 请求方式 和 URL地址 - 绑定事件
.onreadystatechange = () => {}- 异步监听响应函数,判断响应状态
.readyState === 4xhr 对象的请求状态.status >= 200 && xhr.status < 300) || xhr.status === 304服务器响应状态- 使用服务器响应回来的数据
xhr.responseText
发送请求
.send()1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36const xhr = new XMLHttpRequest() // console.log('readyState', xhr.readyState) // readyState 0 // xhr.open('GET', url, true) // xhr.open('GET', '/login?username=john&password=123', true) xhr.open('GET', url) // console.log('readyState', xhr.readyState) // readyState 1 /* 异步代码 */ // xhr.onload = () => {} // 老方法 // xhr.addEventListener('load', () => {}) // 老方法 // 触发`load`事件表示 readyState已经是 4 了 // xhr.error = () => {} // 浏览器控制台模拟断网 // xhr.status === 304 重定向 缓存 xhr.onreadystatechange = () => { // console.log('readyState', xhr.readyState) // readyState 2 // readyState 3 // readyState 4 if(xhr.readyState === 4) { if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){ console.log('xhr.status', xhr.status) // 200 const data = xhr.responseText console.log(data) }else{ console.log('error') } } } /* 异步代码 */ xhr.send()区别
xhr.readyState加载状态和xhr.status服务器HTTP响应状态
实例,以黑马的免费教学API为例:
|
|
1.4.2 xhr 对象的 readyState 属性 ⇧
XMLHttpRequest对象的readyState属性,用来表示 当前 Ajax 请求所处的状态每个 Ajax 请求必然处于以下5个状态中的一个
| 值 | 状态 | 描述 |
|---|---|---|
| 0 | UNSENT |
XMLHttpRequest对象已被创建,但尚未调用 open 方法 |
| 1 | OPENED |
open方法已被调用 |
| 2 | HEADERS_RECIEVED |
send()方法已被调用,响应头页已被接收 |
| 3 | LOADING |
数据接收中,此时response属性中已经包含部分数据 |
| 4 | DONE |
Ajax请求完成,数据传输已经完成或者失败 |
参考
1.4.3 使用 xhr 发起带参数的GET请求 ⇧
使用 xhr 发起带参数的GET请求时,需要在调用
xhr.open()期间,为 URL 地址指定参数即可
|
|
- 在URL地址后面拼接的参数
?id=1,称为 查询字符串 - 查询字符串(URL参数)是指在 URL 末尾加上 用于向服务器发送信息 的字符串(变量)
- 格式为:
- 将英文的
?放在 URL 的末尾,然后再加上参数=值 - 加上多个参数,使用
&符号进行分隔
- 将英文的
一般只在
GET请求中添加使用,将所需发送给服务器的数据添加到 URL 中1 2 3 4 5 6// 不带参数的 URL 地址 http://www.liulongbin.top:3006/api/getbooks // 带参数的 URL 地址 http://www.liulongbin.top:3006/api/getbooks?id=1 // 带两个参数的 URL 地址 http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记
1.4.4 GET请求携带参数的本质 ⇧
发起 GET 请求时,当 URL 需要携带参数的时候,本质上,都是直接将参数以查询字符串的形式,追加到 URL 地址的后面,发送到服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16// 为给定 ID 的 user 创建请求 // 发送 GET 请求(默认的方法) axios('/user/12345') .then(...); // 等价于 axios.get('/user?ID=12345') .then(...); // 等价于 axios.get('/user', { params: { ID: 12345 } }) .then(...);
打开浏览器控制面板查看GET请求
|
|
- URL地址编码
请求 URL: http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=%E8%A5%BF%E6%B8%B8%E8%AE%B0
URL编码
- URL地址中,只允许出现英文相关的字母、标点符号、数字
- URL地址中,不允许出现中文字符
- 如果 URL 中需要包含中文字符,则必须对中文字符进行编码(转义)
- URL 编码原则:使用安全的字符(没有特殊用途或者意义的可打印字符)去表示不安全的字符
通俗理解:使用英文字符表示非英文字符
1 2 3http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记 # 经过 URL 编码之后,URL 地址变为如下格式 http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=%E8%A5%BF%E6%B8%B8%E8%AE%B0
URL编码与解码 API
浏览器提供了 URL 编码与解码的 API,分别是:
encodeURI()编码的函数decodeURI()解码的函数属于浏览器模型 BOM Location 对象,URL 对象,URLSearchParams 对象 MDN
1 2 3 4encodeURI(`西游记`) // '%E8%A5%BF%E6%B8%B8%E8%AE%B0' decodeURI(`%E8%A5%BF%E6%B8%B8%E8%AE%B0`) // '西游记' encodeURI(`西`) // '%E8%A5%BF' decodeURI(`%E8%A5%BF`) // '西'
浏览器自动对 URL 地址进行编码操作,无需关心 URL 地址的编码与解码操作
1.4.5 使用 xhr 发起带参数的POST请求 ⇧
步骤
- 创建
xhr对象 - 调用
xhr.open()函数 设置请求类型和 URL - 调用
xhr.setRequestHeader()设置Content-Type属性(固定写法) - 监听
xhr.onreadystatechange事件 调用
xhr.send()函数,同时要在send()函数的参数中指定要发送的数据1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16// 1. 创建 `xhr` 对象 const xhr = new XMLHttpRequest() // 2. 调用 `xhr.open` 函数 xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook') // 3. 设置 `Content-Type` 属性(固定写法) xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') // 4. 监听 `xhr.onreadystatechange` 事件 xhr.onreadystatechange(() => { if(xhr.readyState === 4 && xhr.status ===200) { const {responseText} = xhr console.log(responseText) } }) // 5. 调用 `xhr.send()`函数 // 同时要在`send()`函数的参数中指定要发送的数据,以查询字符串的形式,无需以 ? 开头 xhr.send('bookname=水浒传&author=施耐庵&publisher=天津出版社')
- send方法的参数就是发送的数据。多种格式的数据 *mdn,都可以作为它的参数。
1.4.6 数据交换格式 ⇧
数据交换格式就是 服务器端与客户端 之间进行数传输与交换的格式
- 在涉及网络传输方面,XML 格式已经过时了
- 区别于 HTML (网页内容的载体),XML 作为数据的载体用来传输和存储数据
- XML 格式臃肿,和数据无关的代码多,传输效率低
- XML 牺牲了体积,增加冗余大小来实现数据语义化
- 需要额外的解析器
- JSON 是主流的交换格式
JavaScript Object Notation ⇧
- 中文翻译为 对象表示法
- JSON 就是 JavaScript 对象和数组 的 字符串表示法
- JSON 使用文本表示一个 JS 对象和数组的信息
- JSON 的本质可以理解为字符串数据,即用字符串来表示 JS 对象数据或数组数据
- JSON 是一种轻量级的文本数据交换格式。
- 用于在计算机和网络之间存储和传输数据
- 相较于 XML 优点为 体积更小、更快、更易解析
- 2.6 回顾复习JSON § ⇧
JSON 的两种结构 ⇧
JSON是用字符串来表示 JavaScript 的对象和数组
所以,JSON中包含 对象 和 数组 两种结构,通过这两种结构的互相嵌套,可以表示复杂的数据结构
JSON 的对象结构 ⇧
对象结构在 JSON 中表现为花括号
{}括起来的内容
- 数据结构形式为
{key: value, key: value, ...}的键值对结构 - 其中,key必须是使用 英文的双括号包裹 的字符串
- value 的数据类型只可以是 字符串、数字、布尔值、数组、对象 和 null 6种
错误范例:
|
|
- 属性名必须由双引号包裹
- 值为字符串类型时,必须由双引号包裹而不是由单引号或反引号
- JSON 中不允许由单引号或反引号表示字符串
- 表示空值时,必须使用
null而不是undefined - 所有含有字符串的值时,必须加双引号而不是单引号或反引号
- 不允许函数作为值或属性
- 不允许在末尾数据项后加逗号
- JSON 中不可以写注释
- JSON 的最外层必须是对象或数组格式
- JSON 不允许使用
undefined、function() {}函数作为 JSON的属性或值
正确范例:
|
|
JSON 的数组结构 ⇧
JSON 的数组结构在 JSON 中表现为以
[]括起来的内容
- 数据结构为
["js", 30, true, {}, [], null] - 数组中数据类型可以是 字符串、数字、布尔值、数组、对象 和 null 6种
合法的 数组形式的 JSON 数据
|
|
|
|
|
|
|
|
注意 JSON 中不支持 bigInt 类型的数据
- JSON 标准(IETF 7159)中定义了 JSON 支持的数据展示类型为 string、number、boolean、null 和这四个基础类型所组成的 object、array 结构
- 其他 JavaScript 类型在编解码时都会被静默消除或转换
- 比如
undefined、function() {}
- 比如
- 使用
json-bigint:可以像JSON.parse一样方便转换(json-bigint 是一个第三方包,可以很好的处理这个问题。 - 参考文章:
JSON 和 JS 对象的关系 ⇧
JSON 是 JS 对象的字符串表示法,他使用文本表示一个 JS 对象的信息,本质是一个字符串
1 2 3 4// 一个对象 const obj = {a: 'Hello', b: 'World'} // 一个 JSON 字符串,本质是一个字符串,遵循了 JSON 的语法规则 const json = '{"a": "Hello", "b": "World"}'
JSON 和 JS 对象的互转 ⇧
要实现从 JSON 字符串转换为 JS 对象,使用
JSON.parse()方法
|
|
要实现从 JS 对象串转换为 JSON 字符,使用
JSON.stringify()方法
|
|
演示
JSON.parse()在 发送 Ajax 请求时的应用
|
|
JSON.parse()转换为结构化的对象从而在 JS 代码中方便处理数据JSON.stringify()转换为JSON字符串用来传输数据
JSON 的序列化和反序列化 ⇧
把 数据对象 转换为 字符串 的过程,叫序列化
- 调用
JSON.stringify(JSONObject)方法的操作,叫 JSON 序列化
把 字符串 转换为 数据对象 的过程,叫反序列化
- 调用
JSON.parse(JSONString)方法的操作,叫 JSON 反序列化
1.5 封装 Ajax 函数 ⇧
导入自己封装的 Ajax 函数
- 可以实现 调用自定义 myAjax 函数,发起 Ajax 请求
接受一个配置对象作为参数,配置对象中可以配置如下属性:
- method: 请求类型
- url: 请求地址
- data: 请求参数对象
successCb: 请求成功后的回调函数
1 2 3 4 5 6 7import myAjax from 'myAjax.js' myAjax({ method: '', // 请求类型 url: '', // 请求地址 data: {}, // 请求参数对象 successCb: () => {}, // 请求成功后的回调函数 })
处理 data 参数
- 用户提交数据时,以对象形式提交参数
- 需要把 data 对象,转化成查询字符串的格式,提交给服务器
因此需提前定义
resolveData函数如下:1 2 3 4 5 6 7 8 9 10 11 12/* * 处理 data 参数 * @param {Record<string, string>} data需要发送到服务器的数据 * @returns {string} 返回拼接好的查询字符串 */ function resolveData(data) { const arr = [] for(let k in data) { arr.push(`${k}=${data.k}`) } return arr.join('&') }
定义
myAjax函数
需要创建 xhr 对象,并监听
onreadystatechange事件1 2 3 4 5 6 7 8 9 10 11 12 13function myAjax(options) { const {data, successCb} = options const xhr = new XMLHttpRequest() // 拼接查询字符串 const qs = resolveData(data) // 监听请求状态改变事件 xhr.onreadystatechange = () => { if(xhr.readyState === 4 && xhr.status === 200) { const res_JSONObj = JSON.parse(xhr.responseText /* xhr.responseText JSONString*/) successCb(res_JSONObj) } } }
判断请求类型
不同的请求类型,对应 xhr 对象的不同操作。因此需要对请求类型进行条件分支的判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19... const reqMap = { 'GET': () => { xhr.open(method, `${url}?${qs}`) xhr.send() }, 'POST': () => { xhr.open(method, url) xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send(qs) }, 'PUT': () => {}, 'DELETE': () => {}, 'HEAD': () => {}, 'OPTION': () => {}, } reqMap[`${method.toUpperCase()}`]() ...
完整的 myAjax 函数
|
|
发送请求
|
|
1.6 如何使用XMLHttpRequest Level2中提供的新特性 ⇧
XMLHttpRequest Level1的缺点
- 只支持文本数据的传送,无法用来读取和上传二进制文件。
- 传送和接收数据时,没有进度信息,只能提示有没有完成。
- 受到”同域限制”(Same Origin Policy),只能向同一域名的服务器请求数据
XMLHttpRequest Level2的优点
- 可以设置 HTTP 请求的时限
- 可以使用 FormData 对象管理表单数据
- 可以上传文件
- 可以请求不同域名下的数据(跨域请求)
- 可以获取服务器端的二进制数据
XMLHttpRequest Level2可以获得数据传输的进度信息,能实现fetch API目前无法做到的事情,例如跟踪上传进度
1.6.1 使用XMLHttpRequest Level2设置 HTTP 请求的时限 ⇧
有时, Ajax 操作很费时,而且无法预知要花多少时间。如果网速慢(模拟slow 3G)用户等待时间久
XMLHttpRequest Level2的timeout属性实现可设置 HTTP 请求的时限- 超过设置的时限,自动停止 HTTP 请求
监听 timeout 事件
xhr.ontimeout,用来指定时间超限时的回调函数1 2 3 4 5const xhr = new XMLHttpRequest() xhr.timeout = 3000 // 类型为number 单位为毫秒 xhr.ontimeout = () => { console.log('请求超时') }在 node 环境下的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22// yarn add -D xmlhttprequest-ts import {XMLHttpRequest} from 'xmlhttprequest-ts' // XMLHttpRequest level2 // yarn add -D xhr2 // import XMLHttpRequest from 'xhr2' // XMLHttpRequest level2 const xhr = new XMLHttpRequest(); // timeout xhr.timeout = 10 xhr.ontimeout = () => { console.log('请求超时了') } xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks') xhr.onreadystatechange = () => { if (xhr.readyState === 4 && xhr.status === 200) { console.log("-> xhr.responseText", xhr.responseText); } } xhr.send()
1.6.2 使用XMLHttpRequest Level2使用 FormData 对象管理表单数据 ⇧
Ajax 操作往往用来提交表单数据,为了方便表单处理,HTML5增加了一个
FormData内置对象,可以模拟表单操作
- 新建
FormData对象实例fd - 可多次调用
FormData实例fd的.append(key: string, value: unknown)方法,为FormData添加表单项 - 创建
xhr实例对象 - 调用
xhr.open(method, url)指定请求类型与地址,method一般为POST - 监听
onreadystatechange事件,指定回调函数 - 调用
xhr.send(fd),将实例fd作为参数发送请求,直接提交 无需设置
xhr.setHeader的数据类型,内部自动设置xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19// 新建 FormData 对象实例 fd const fd = new FormData() // 可多次为 FormData 添加表单项 fd.append('uname', 'zz') fd.append('upwd', '123456') // 创建 xhr 实例对象 const xhr = new XMLHttpRequest() // 指定请求类型与地址 xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata') // 直接提交 FormData 对象实例,将实例fd作为参数发送请求 // 与提交网页表单的效果一样 xhr.onreadystatechange = () => { if(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300) { console.log(JSON.parse(xhr.responseText)) } } xhr.send(fd) // 无需设置 xhr.setHeader 的数据类型
FormData对象也可以用来获取网页表单的值
获取网页中的
<form>标签元素作为参数传入new FormData()实例对象中,发送请求1 2 3 4 5 6 7 8 9 10 11 12 13 14 15// 使用 Ajax 的形式提交表单 // 获取表单元素 const form = document.querySelector('#form1') // 监听表单元素的 submit 事件 form.addEventListener('submit', (e) => { e.preventDefault() // 使用 Ajax 的形式提交表单避险阻止默认提交行为 // 根据 form 表单创建 FormData 对象,会自动将表单数据填充到 FormData 对象中,无需手动 调用 .append 方法 const fd = new FormData(form) // 无需设置 `xhr.setHeader` 的数据类型 const xhr = new XMLHttpRequest() xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata') xhr.onreadystatechange = () => {} xhr.send(fd) })
index.html
|
|
- 设置输入框标签的
autocomplete="off",关闭自动填充
参考
JS原生实现
FormData获取表单数据
|
|
简单封装
FormData.vue仓库地址
|
|
1.6.3 使用XMLHttpRequest Level2上传文件 ⇧
- 上传图片API
- 接口:
http://www.liulongbin.top:3006/api/upload/avatar - 请求类型:
POST - 请求参数:
{'avatar': fileObj} - 返回值
- 接口:
实现步骤
- 定义UI结构
- 验证是否选择了文件
- 向
FormData中追加文件 - 使用 xhr 发起上传文件的请求
- 监听
onreadystatechange事件
- 定义UI结构
|
|
- 验证是否选择了文件
|
|
- 获取上传文件按钮
- 为按钮添加点击事件监听
- 获取选择的文件列表 使用
<input type="file"/>元素的API.files
- 向
FormData中追加文件
|
|
- 创建 FormData 对象
- 向 FormData 中追加文件
files[0]
- 使用 xhr 发起上传文件的请求
|
|
- 创建 xhr 对象
- 调用 open 函数,指定请求类型与 URL 地址,上传文件的请求类型必须为 POST
- 监听
onreadystatechange事件 - 发起请求
封装
Upload.vue组件
|
|
1.6.4 使用XMLHttpRequest Level2获得数据传输的进度信息 ⇧
在
XMLHttpRequest 2.0对象中,可以通过监听xhr.upload.onprogress事件,来获取到文件上传的进度
- 监听 xhr.upload 的 onprogress 事件,设置回调函数
- 事件形参
e e.lengthComputable当前上传的资源是否具有可计算的长度e.loaded文件已传输的字节e.total需传输文件的总字节1 2 3 4 5 6 7 8 9 10 11// 创建 xhr 对象 const xhr = new XMLHttpRequest() // 监听 xhr.upload 的 onprogress 事件 xhr.upload.onprogress = (e) => { // e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度 if(e.lengthComputable) { // e.loaded 已传输的字节 // e.total 需传输的总字节 const percentComplete = Math.ceil((e.loaded / e.total) * 100) } }
可以设置浏览器Network面板中slow 3G 查看上传过程
|
|
动态设置进度条
|
|
1.6.5 使用XMLHttpRequest Level2请求不同域名下的数据(跨域请求) ⇧
设置严格检查
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
参考
- XMLHttpRequest MDN
- XMLHttpRequest 现代 JavaScript 教程
XMLHttpRequest Level 2使用指南 阮一峰 2012New Tricks in XMLHttpRequest2 2011
1.7 复习使用axios发起 Ajax 请求 ⇧
1.8 实现文件上传与loading效果 ⇧
2 AJAX应用 ⇧
2.1 AJAX加载CSS § ⇧
以前使用
<link rel="stylesheet" href="/style.css">引入
|
|
- 这里
--<link rel="stylesheet" href="/style.css">中的/style.css"是路由path的请求路径
server.js
|
|
style.css
|
|
使用 AJAX 加载 CSS 的四个步骤 ⇧
在
server.js里写路由
|
|
- 区别路由
path的请求路径和fs.readFileSync('src/xxx')的查找文件目录路径
index.html
|
|
index.html里写的所有路径(/style.css和/main.js),必须和路由的path路径一致,才能生效- 创建一个 button 测试
在
main.js里写
|
|
- 创建
HttpRequest对象 (全称是XMLHttpRequest) - 调用对象的
open方法 - 监听对象的
onload和onerror事件 - 调用对象的
send方法(发送请求) - 获取资源用
request.open('GET', '/xxx');,只用两个参数,mdn 中后面的参数不用XMLHttpRequest.open() MDN
而
request.response就是响应得到的文件内容
要使这段内容生效,就在外包裹一层对应的标签
1 2 3 4// 将响应的内容,用对应的标签包裹,插入html页面相应位置 const style = document.createElement('style') // 创建 style 标签 style.innerHTML = request.response // 填写 style 内容 document.head.appendChild(style) // 插入head标签里
触发
onerror事件
|
|
server.js路径写错:你输入的路径不存在对应的内容1 2 3 4 5 6 7 8//... else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(`你输入的路径不存在对应的内容`) response.end() } //...只会渲染路径错误时的路由,并不触发
onerror事件onerror对AJAX的支持不好
在第3步中,AJAX一般改用
onreadystatechange事件,不用onload和onerror
- 用对象的
status属性,即状态码来判断,响应是否成功 注意
onreadystatechange全小写1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22getCSS.onclick = () => { const request = new XMLHttpRequest() request.open('GET', '/style.css'); request.onreadystatechange = () => { // 监听对象的 readyState属性 // console.log(request.readyState) // 2 3 4 if (request.readyState === 4) { // console.log('下载完成') // 下载完成,但不知道下载成功还是失败 if (request.status >= 200 && request.status < 300) { // 将响应的内容,用对应的标签包裹,插入html页面相应位置 const style = document.createElement('style') // 创建 style 标签 style.innerHTML = request.response // 填写 style 内容 document.head.appendChild(style) // 插入head标签里 } else { console.log('加载CSS失败') } } } request.send() }在事件处理函数里操作 CSS 文件内容
XMLHttpRequest.readyState相关状态,4 表示下载完成
2.2 AJAX加载JS § ⇧
以前使用
<script src="main.js"></script>引入
使用 AJAX 加载 JS 的四个步骤 ⇧
server.js
|
|
index.html
|
|
- 创建
HttpRequest对象 (全称是XMLHttpRequest) - 调用
open方法 - 监听对象的
onreadystatechange事件 - 调用对象的
send方法(发送请求)
main.js
|
|
- 在事件处理函数里操作 JS 文件内容
- 将响应的内容,用对应的标签包裹,插入html页面相应位置
- AJAX下载并执行响应的内容
2.3 AJAX加载HTML § ⇧
以前没有加载过 HTML
在目录
src/下创建测试用indexOld.html,不写全,只写个标签1 2<h2>AJAX demo 2</h2> <div style="background-color: bisque;border: 1px solid orange;width:300px;height:300px;">动态内容</div>
配置路由
server.js
|
|
index.html加测试按钮
|
|
使用 AJAX 加载 HTML 的四个步骤 ⇧
- 创建
HttpRequest对象 - 调用对象的
open方法 - 监听对象的
onreadystatechange事件 调用对象的
send方法1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18//... // AJAX 加载 HTML getHTML.onclick = () => { const request = new XMLHttpRequest request.open('GET', '/indexOld.html') request.onreadyStatechange = () => { if (request.readyState === 4 && request.status >= 200 && request < 300) { // 创建 div 标签 const div = document.createElement('div') // 填写 div 内容 div.innerHTML = request.response // 插到body里 document.body.appendChild(div) } } request.send() } //...
- 在事件处理函数里操作
HTML文件内容 - 动态展示
index.html - 控制台
Network查看请求 点Preview预览请求的页面 - 点
Response看源代码 - 把页面拆成不同的部分,在用户点击时,请求这个部分
- 可以请求一小块 HTML,而
iframe是请求整个网页,更加臃肿 AJAX可以做到轻量级的请求,任意 HTTP 支持的文件类型
2.4 AJAX加载XML § ⇧
使用 AJAX 加载 XML 的四个步骤 ⇧
server.js
|
|
index.html
|
|
getXML.xml
|
|
- 创建
HttpRequest对象(全称是XMLHttpRequest) - 调用对象的
open方法 - 监听对象的
onreadystatechange事件 - 调用对象的
send方法(发送请求)
main.js
|
|
- 在事件处理函数里操作
responseXML request.responseXML是 DOM 对象
2.5 AJAX应用小结 § ⇧
HTTP 可以请求的类型 ⇧
- 可以请求
HTMLCSSJS… - 设置正确的
Content-Type - 响应的内容,用对应的标签包裹,插入html页面相应位置
- 知道怎么解析,就可以使用
解析方法 ⇧
- 得到 CSS 后生成
style - 得到 JS 后生成
script - 得到 HTML 使用
innerHTML和DOM API - 得到 XML 后使用
responseXML和DOM API - 不同类型的数据有不同的解析办法
2.6 回顾复习JSON § ⇧
JavaScript Object Notation
- JSON 是 轻量级的数据交换格式语言
- 和HTML CSS JS一样是门独立的语言
- 和HTML XML Markdown 是 标记语言,用来展示数据
- 中文官网
- 一页纸
- 铁轨图
支持的类型 ⇧
string只支持双引号,不支持单引号、反引号和无引号number支持科学技术法booltrue和falsenull没有undefinedobjectarray
区别于 JS 的类型
- 不支持函数与变量(即不支持引用)
和JS语法的区别:
- JSON 的字符串必须用双引号。
- JSON 无法表示 undefined,只能表示 “undefined”
- JSON 无法表示函数
- JSON 的对象语法不能有引用
2.7 AJAX加载JSON § ⇧
server.js
|
|
getJSON.json
|
|
index.html
|
|
使用 AJAX 加载 JSON 的四个步骤 ⇧
- 创建
HttpRequest对象(全称是XMLHttpRequest) - 调用对象的
open方法 - 监听对象的
onreadystatechange事件 - 调用对象的
send方法(发送请求)
main.js
|
|
- 在事件函数里使用
JSON.parse JSON.parse把符合 JSON 语法的字符串变成对应的对象或者是其他东西
2.8 JS内置对象 window.JSON § ⇧
JSON.parse('string') ⇧
- 解析字符串
- 将符合
JSON语法的字符串转换成JS对应类型的数据 - 返回值 Object 类型, 对应给定 JSON 文本的对象/值
JSON字符串 -> JS 数据- 转换成的不一定是对象,可以是 JSON 值类型的其他类型( typeof )
- 由于 JSON 只有六种类型,所以转成的数据也只有6种
- 如果不符合
JSON语法,则直接抛出一个Error对象 - 一般用
try...catch捕获错误 异常 若传入的字符串不符合 JSON 规范,则会抛出 SyntaxError 异常
1 2 3 4 5 6 7 8 9let object try{ object = JSON.parse(`{'name':'frank'}`) }catch(error){ console.log('Error!') console.log(error) object = {"name":"no name"} } console.log(object)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19const json = '{"result":true, "count":42}' const obj = JSON.parse(json) console.log(obj.count) // expected output: 42 console.log(obj.result) // expected output: true JSON.parse('{}'); // {} JSON.parse('true'); // true JSON.parse('"foo"'); // "foo" JSON.parse('[1, 5, "false"]'); // [1, 5, "false"] JSON.parse('null'); // null JSON.parse() 不允许用逗号作为结尾 // both will throw a SyntaxError JSON.parse("[1, 2, 3, 4, ]"); JSON.parse('{"foo" : 1, }');
JSON.stringify(value) 序列化 ⇧
- 是
JSON.parse()的逆运算 - JS 数据 ->
JSON字符串 - 即序列化成 一个 JSON 字符串的值
- 将值转换为相应的JSON格式
- 由于 JS 的数据类型比 JSON 多,所以不一定成功
如果失败,则直接抛出一个
Error对象1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51const obj = {"hi": "Ho", "fn": () => {}} JSON.stringify(obj) // 不报错 直接忽略不合法的类型 JSON.stringify({}); // "{}" JSON.stringify(true); // "true" JSON.stringify("foo"); // ""foo"" JSON.stringify([1, "false", false]); // "[1,"false",false]" JSON.stringify({ x: 5 }); // "{"x":5}" JSON.stringify({x: 5, y: 6}); // "{"x":5,"y":6}" JSON.stringify([new Number(1), new String("false"), new Boolean(false)]); // '[1,"false",false]' JSON.stringify({x: undefined, y: Object, z: Symbol("")}); // '{}' JSON.stringify([undefined, Object, Symbol("")]); // '[null,null,null]' JSON.stringify({[Symbol("foo")]: "foo"}); // '{}' JSON.stringify({[Symbol.for("foo")]: "foo"}, [Symbol.for("foo")]); // '{}' JSON.stringify( {[Symbol.for("foo")]: "foo"}, function (k, v) { if (typeof k === "symbol"){ return "a symbol"; } } ); // undefined // 不可枚举的属性默认会被忽略: JSON.stringify( Object.create( null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } } ) ); // "{"y":"y"}"
2.9 AJAX综合应用:加载分页 § ⇧
2.9.1 加载列表 ⇧
- 用户打开页面,开到第一页数据
- 用户点击下一页,看到第二页数据
- 用户点击下一页,看到第三页数据
- 用户点击下一页,提示没有更多了
/db/page1.json page2.json page3.json
- 前后端不分离的渲染
index.html
|
|
server.js
|
|
- 从数据库中拿出,拼接字符串
main.js
|
|
2.9.2 优化点 ⇧
- 在点击第三页的时候就禁用下一页按钮
main.js
|
|
2.9.3 请求天气数据 ⇧
|
|
2.9.4 发送POST请求 ⇧
应用场景:涉及到登录、注册、用户填写信息(调查问卷)需提交,而不是查询的场合时,要用POST请求
|
|
2.9.3 注册登录发送POST请求 ⇧
默认的
Content-type,是multipart/form-data
|
|
2.9.4 POST ⇧
|
|
|
|
3. 手写AJAX § ⇧
使用原生 JS 写出一个 AJAX 请求
|
|
后台的
server.js,处理请求
|
|
4. ajax 的简陋封装 § ⇧
|
|
5. fetch代替JS原生AJAX § ⇧
AJAX的API设计并不是很好,输入、输出、状态都在同一个接口管理,容易写出非常混乱的代码。
- Fetch API 是一种ES6规范,用来取代XMLHttpRequest对象
- 两个特点,一是接口合理化,Ajax 将所有不同性质的接口都放在 XHR 对象上,而 Fetch 将它们分散在几个不同的对象上,设计更合理;
二是 Fetch 操作返回Promise对象,避免了嵌套的回调函数。
1 2 3 4 5 6let url = 'http://api.jirengu.com/getWeather.php?city=北京' fetch(url).then(response => {return response.json()}) .then(data => { document.body.innerText = data.results[0].weather_data[0].weather })
POST
|
|
使用githubpagesmock数据 § ⇧
同步开发,约定格式,模拟数据,前后端联调
使用easymock来mock数据 § ⇧
|
|
轮询与长轮询Comet聊天室 ⇧
双工通信:每隔固定时间发一次请求
- AJAX轮询: 简陋的聊天室
- 长轮询(减少请求数量)凑合聊天室
- WebSocket 聊天室
客户端
- 发请求,等待响应(pending)
- 当响应时,再次发一个请求
服务器端
- 请求到来,如果没新数据,则不发响应
- 当有新数据,需要通知客户端,再响应
- AJAX.pdf
- XMLHttpRequest与fetch.pdf
- server.js 所有代码
- nodejs-test By Fang
- 【HTTP非全解】请求和响应 & Node.Js Server
- 「每日一题」JSON 是什么?
参考文章 ⇧
- XMLHttpRequest MDN
- XMLHttpRequest 对象 Wangdoc
- Fetch API 教程 Wangdoc
- 网络请求 XMLHttpRequest 现代 JavaScript 教程