一篇文章彻底搞懂 XML、AJAX、XHR、Fetch、Axios、Token、JWT、鉴权
前言
刚学习前端的时候,经常会看到下面这些名词:
XML
JSON
AJAX
XMLHttpRequest(XHR)
Fetch
Axios
Token
JWT
鉴权(Authentication / Authorization)
很多新手都会有一个疑问:
它们到底是什么?为什么名字这么多?它们之间到底有什么关系?
其实,这些东西并不是同一级别的概念。
如果把它们全部混在一起理解,就会越来越乱。
本文尽量不用晦涩的专业术语,而是通过生活中的例子,一次性把它们讲清楚。
一、先看整体关系(最重要)
先记住下面这张图。
浏览器(前端)
│
点击登录、获取数据、提交订单
│
▼
AJAX(一种开发思想)
│
┌────────────┴────────────┐
│ │
▼ ▼
XMLHttpRequest Fetch
(旧) (新)
▲
│
Axios(第三方封装)
│
▼
请求服务器
│
▼
返回 JSON / XML 等数据
│
▼
浏览器显示页面
而登录之后,又会变成:
登录
↓
服务器生成 Token(通常是 JWT)
↓
浏览器保存 Token
↓
以后每次请求自动携带 Token
↓
服务器鉴权
↓
允许访问接口
如果能理解这两张图,后面的内容基本都会明白。
二、XML 是什么?
一句话:
XML 是一种数据格式。
它的作用就是:
规定数据应该怎么写。
例如:
<user>
<name>Tom</name>
<age>20</age>
</user>
它表示:
用户:
名字:Tom
年龄:20
它最大的特点就是:
全部使用标签。
例如:
<姓名>
<年龄>
<电话>
<地址>
机器看到这些标签以后,就知道每一段内容代表什么。
XML 为什么越来越少了?
因为后来出现了 JSON。
例如:
XML:
<user>
<name>Tom</name>
<age>20</age>
</user>
JSON:
{
"name":"Tom",
"age":20
}
JSON 更短。
更容易阅读。
更容易解析。
所以现在 Web 接口几乎都是 JSON。
因此:
XML 是以前主流的数据格式,现在更多用于一些老系统、配置文件或特殊行业接口;JSON 才是现代 Web API 的主流。
三、AJAX 是什么?
很多人以为 AJAX 是一个库。
其实不是。
AJAX 是一种开发思想。
它的意思就是:
网页不用整体刷新,也可以和服务器通信。
以前的网站:
点击登录
↓
整个网页刷新
↓
重新下载 HTML
↓
重新显示
后来:
点击登录
↓
偷偷请求服务器
↓
服务器返回数据
↓
局部更新页面
整个网页不会闪一下。
微信网页版。
QQ。
淘宝。
抖音网页版。
几乎全部都是这样。
这就是 AJAX。
所以:
AJAX 并不是代码。
AJAX 是:
网页局部更新的一种技术思想。
四、XHR 是什么?
XHR 全名:
XMLHttpRequest
它是浏览器提供的一个对象。
以前:
想实现 AJAX。
只能使用它。
例如:
const xhr = new XMLHttpRequest();
xhr.open("GET","/api/user");
xhr.send();
然后:
监听:
xhr.onreadystatechange = function(){
}
代码很多。
逻辑复杂。
维护困难。
所以后来浏览器推出了 Fetch。
五、Fetch 是什么?
一句话:
Fetch 是浏览器官方的新一代请求 API。
例如:
const res = await fetch("/api/user");
const data = await res.json();
相比 XHR:
更加简单。
更加现代。
支持 Promise。
支持 async/await。
因此:
现在很多新项目直接使用 Fetch。
六、Axios 是什么?
Axios 不是浏览器提供的。
它是别人写好的第三方库。
作用就是:
把 Fetch/XHR 再封装一层。
例如:
const res = await axios.get("/api/user");
直接:
res.data
就可以拿到数据。
不用:
await res.json()
Axios 还能帮助开发者处理很多重复工作。
例如:
自动添加 Token
请求超时
请求重试
请求拦截
响应拦截
上传文件
下载文件
统一错误处理
所以企业项目大量使用 Axios。
七、XHR、Fetch、Axios 的关系
一句话:
AJAX
│
├── XHR(旧)
│
└── Fetch(新)
Axios
│
└── 对请求进行了进一步封装
可以理解成:
AJAX 是一种理念。
XHR、Fetch 是浏览器提供的工具。
Axios 是第三方工具。
八、什么是 Token?
一句话:
Token 就是一张数字通行证。
为什么需要它?
假设没有 Token。
登录:
账号
密码
查看订单:
账号
密码
查看购物车:
账号
密码
修改地址:
账号
密码
每一次请求。
都发送密码。
既麻烦。
也不安全。
于是:
登录成功以后:
服务器生成:
Token
例如:
eyJhbGc...
浏览器保存。
以后所有请求:
只发送:
Token
服务器看到以后:
知道你是谁
允许访问
整个过程:
登录
↓
获得 Token
↓
以后所有请求带 Token
↓
服务器识别身份
九、Axios 为什么可以自动带 Token?
如果不用 Axios。
你可能要写:
fetch("/api/user",{
headers:{
Authorization:"Bearer xxxxx"
}
})
每个接口都要写。
几十个接口。
上百个接口。
非常麻烦。
Axios 有一个功能:
请求拦截器。
可以理解成:
公司的门卫。
每一辆快递车出去。
门卫都会自动:
检查有没有 Token
↓
没有?
↓
自动放进去
于是:
开发者根本不用管。
所有请求:
都会自动携带 Token。
十、JWT 是什么?
很多人以为:
JWT 和 Token 是一样的。
其实不是。
关系是:
Token
├── JWT
├── UUID Token
├── Session Token
└── 其它格式
所以:
JWT 是 Token 的一种实现方式。
也是目前最常见的一种。
JWT 长这样:
xxxxx.yyyyy.zzzzz
中间三个部分:
Header
Payload
Signature
Header
表示:
我是 JWT
我用了什么算法
Payload
里面放的是:
用户ID
用户名
角色
过期时间
注意:
这里的数据通常只是编码(Base64URL),不是加密。
所以:
不要放密码。
不要放银行卡。
不要放身份证。
Signature
这是最重要的。
它可以理解成:
防伪印章。
如果有人:
偷偷修改:
role=user
改成:
role=admin
服务器验签以后:
立即发现:
签名错误
拒绝访问
所以:
JWT 靠签名保证:
没有被篡改。
十一、什么叫鉴权?
一句话:
鉴权就是服务器检查:"你有没有权限访问这个接口?"
例如:
你进入公司。
保安:
请出示工牌。
工牌:
合法
↓
放行
没有工牌:
禁止进入
服务器也是一样。
浏览器请求:
GET /api/order
服务器:
第一件事情不是查订单。
而是:
先检查 Token
如果:
Token 不存在
Token 已过期
Token 被篡改
服务器直接返回:
401 Unauthorized
意思就是:
身份验证失败。
这个过程。
就叫:
鉴权。
十二、完整工作流程
把所有知识串起来。
① 用户登录
↓
② 输入账号密码
↓
③ 服务器验证
↓
④ 生成 JWT
↓
⑤ 浏览器保存 JWT
↓
⑥ Axios 自动携带 JWT
↓
⑦ 请求接口
↓
⑧ 服务器鉴权
↓
⑨ 返回 JSON 数据
↓
⑩ 浏览器更新页面
十三、总结(记住这一张图即可)
XML
│
├── 数据格式(较老)
JSON
│
└── 数据格式(现代主流)
AJAX
│
└── 不刷新页面请求服务器的思想
XHR
│
└── 浏览器旧请求 API
Fetch
│
└── 浏览器新请求 API
Axios
│
└── 第三方请求库,封装了很多功能
Token
│
└── 登录后的身份凭证
JWT
│
└── Token 的一种常见格式
鉴权
│
└── 服务器检查 Token 是否合法、是否允许访问
最简单的理解
如果把整个前后端通信比作进入一家公司:
AJAX:不用每次都重新进公司,只需要去对应部门办事。
XHR / Fetch:负责把你送到各个部门的交通工具,XHR 是老车,Fetch 是新车。
Axios:一个更高级的司机,不仅开车,还会帮你带工牌、处理异常、规划路线。
XML / JSON:文件的书写格式,JSON 是现在最常用的。
Token:公司的工牌,登录成功后发放,以后每次办事都带着它。
JWT:一种最常见的工牌格式,里面记录了身份信息,并带有防伪签名。
鉴权:门卫检查工牌是否合法、有没有过期、有没有被伪造,决定是否允许进入。