0%

axios原理及面试题

axios原理

createInstance底层根据默认设置 新建一个Axios对象, axios中所有的请求[axios, axios.get, axios.
post等…]内部调用的都是Axios.prototype.request, 将Axios.prototype.request的内部this绑定到新建的
Axios对象上, 从而形成一个axios实例。新建一个Axios对象时,会有两个拦截器,request拦截器,response拦
截器。

请求拦截器

请求拦截器的作用是在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易。

1
2
3
4
5
6
7
8
axios.interceptors.request.use(function(config) {
// 在发送请求之前做些什么,例如加入token
.......
return config;
}, function(error) {
// 对请求错误做些什么
return Promise.reject(error);
});

具体实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const service = axios.create({
timeout: 15000
})
// 在请求头中加token
service.interceptors.request.use(
config => {
// 判断是否存在token,如果存在的话,则每个http header都加上token
let token = sessionStorage.getItem('token')
if (!config.headers.hasOwnProperty('token') && token) {
if (config.url !== "/api_src/sm/auth/refreshToken") {
config.headers.Authorization = "Bearer " + token
}
}
return config
},
error => {
return Promise.reject(error)
})
接口认证方式:Bearer Token

因为HTTP协议是开放的,可以任人调用。所以,如果接口不希望被随意调用,就需要做访问权限的控制,认证是好的用户,才允许调用API。

定义:为了验证使用者的身份,需要客户端向服务器端提供一个可靠的验证信息,称为Token,这个token通常由Json数据格式组成,通过hash散列算法生成一个字符串,所以称为Json Web Token(Json表示令牌的原始值是一个Json格式的数据,web表示是在互联网传播的,token表示令牌,简称JWT)

JWT分为三部分:

第一部分:头部
{
“typ” : “JWT”,     (typ:类型)
“alg” : “HS256” (alg:算法,HS256表示哈希算法的mac值。SHA256/HmacSHA256,SHA256表示直接加密,HmacSHA256表示用秘钥进行加密。SHA(Secure[sɪˈkjʊə(r)]  Hash Algorithm [ˈælgərɪðəm],安全散列算法)
HMAC(Hash Message Authentication [ɔ:ˌθentɪ’keɪʃn] Code,散列消息鉴别码))
}

第二部分(Claim正文部分)
{
“iss” : “joe”, (issuer,发布者)
“exp”: 1300819380, (expiration[ˌekspəˈreɪʃn]  time 过期时间,毫秒数计算)
http://example.com/is_root" :true(主题)
}

第三部分:签名(将上面的两个部分组合在一起+本地信息做的一个的签名(头部在前)
网络解释: 签名是把header和payload(载荷)对应的json结构进行base64url编码之后得到的两个串,用英文句点号拼接起来,然后根据header里面alg指定的签名算法生成出来的。
https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-19

  1. 令牌的好处:避免在使用中不断的输入账号和密码,比较安全
  2. 如果要测试带token的接口,首先要进行登录,登录成功会有个token信息,向api接口发送请求的时候必须带上这个token,故需要做2次请求(1,登录,拿到token 2,正式对接口进行测试)

这个时候头部会多一个authorization。

authorization可能在头部,也可能直接跟在请求行里面

1
http://www.xxx.com/ada?token=xxxxx
  1. 注意点:

1)token一般有时间限制。测试前需要跟开发确认token可以用多久,什么时候算token失效
2)token放在哪儿,怎么传回去,需要有开发文档,或者咨询开发,登录成功返回的token需要了解从什么地方获取(可以通过录制进行查看)

响应拦截器

响应拦截器的作用是在接收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页。

1
2
3
4
5
6
7
8
axios.interceptors.response.use(function(response) {
// 在接收响应做些什么,例如跳转到登录页
......
return response;
}, function(error) {
// 对响应错误做点什么
return Promise.reject(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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// response interceptor
service.interceptors.response.use(
response => {
const res = response.data
if (res.success || res.FLAG === 'SUCCESS' || res.retCode === '200' || res.status === 200) {
return Promise.resolve(res)
} else if (res.code === '0420') { //不允许访问
Message({
message: res.msg || res.MESSAGE || res.message || 'Error',
showClose: true,
type: 'error',
duration: 2000
})
return Promise.reject(res)
} else if (res.code === '1000') { //异常
Message({
message: 'token信息失效,请重新登录',
showClose: true,
type: 'error',
duration: 2000
})
storageClear()
router.replace({
path: '/login' // 到登录页重新获取token
})
return Promise.reject(res)
} else if (res.code === '1010') { //失效
// 更新token的方法
const tokenParams = sessionStorage.getItem("refreshToken") ?? ''
if (tokenParams) {
let reback = doRequest(tokenParams, service, response)
return Promise.resolve(reback)
}
} else {
Message({
message: res.msg || res.MESSAGE || res.message || 'Error',
showClose: true,
type: 'error',
duration: 2000
})
return Promise.reject(res)
}
},
error => {
if (error.response?.status === 401) {
Message({
message: 'token信息失效,请重新登录',
showClose: true,
type: 'error',
duration: 2000
})
storageClear()
router.replace({
path: '/login' // 到登录页重新获取token
})
return Promise.reject(error)
} else {
Message({
message: error.message,
showClose: true,
type: 'error',
duration: 2000
})
return Promise.reject(error)
}
}
)
async function doRequest(tokenParams, service, response) {
sessionStorage.setItem("refreshTokenFlag", '1')
let getBack = refreshToken(tokenParams, service, response)
return getBack

}

axios的特点有哪些

  1. Axios 是一个基于 promise 的 HTTP 库,支持promise所有的API
  2. 它可以拦截请求和响应
  3. 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
  4. 安全性更高,客户端支持防御 XSRF

axios有哪些常用方法

  1. axios.get(url[, config]) //get请求用于列表和信息查询
  2. axios.delete(url[, config]) //删除
  3. axios.post(url[, data[, config]]) //post请求用于信息的添加
  4. axios.put(url[, data[, config]]) //更新操作

说下你了解的axios相关配置属性

url是用于请求的服务器URL

method是创建请求时使用的方法, 默认是get

baseURL将自动加在url前面,除非url是一个绝对URL。它可以通过设置一个baseURL便于为axios实例的方法传递相对URL

transformRequest允许在向服务器发送前,修改请求数据,只能用在’PUT’, ‘POST’和’PATCH’这几个请求方法

headers是即将被发送的自定义请求头
headers:{‘X-Requested-With’:’XMLHttpRequest’},

params是即将与请求一起发送的URL参数,必须是一个无格式对象(plainobject)或URLSearchParams对象
params:{
ID:12345
},

auth表示应该使用HTTP基础验证,并提供凭据
这将设置一个Authorization头,覆写掉现有的任意使用headers设置的自定义Authorization头
auth:{
username:’janedoe’,
password:’s00pers3cret’
},

‘proxy’定义代理服务器的主机名称和端口
auth表示HTTP基础验证应当用于连接代理,并提供凭据
这将会设置一个Proxy-Authorization头,覆写掉已有的通过使用header设置的自定义Proxy-Authorization头。
proxy:{
host:’127.0.0.1’,
port:9000,
auth::{
username:’mikeymike’,
password:’rapunz3l’
}
},

  • 本文作者: David Xue
  • 本文链接: https://xdw-h.github.io/63/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!