Vue-resource 和 vue-axios 拦截器

拦截器简介

顾名思义,拦截器主要是拦截,放到 Vue 里面指对 Vue 发出的 http 请求和响应进行拦截,并可以对拦截的请求或响应做一些特殊的处理

拦截器能做的

  • 添加统一的request的参数
    • 比如header中加入 X-Requested-With,比如客户端需要实现sign和token的验证机制,比如你可以写 $http.get('/files', params),拦截器帮你拼接成 http://www.xxxx.com/1/files 这样的请求地址
  • 处理统一的 responseError
    • 比如重连机制,拿到 error.code 错误码重连,比如 token 过期,重新拿到 token 再次s end request
    • 比如统一报错信息,给所有返回的404来个提示也会很酷

axios 拦截器

1、安装 axios

1
npm install axios --save-dev

2、在根目录的 config目录下新建文件 axios.js,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import axios from 'axios'

// 配置默认的host,假如你的API host是:http://api.htmlx.club
axios.defaults.baseURL = 'http://api.htmlx.club'


// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
});


// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error)
});

3、在 main.js 中进行引用,并配置一个别名($ajax)来进行调用:

1
2
3
4
import axios from 'axios'
import '../config/axios'

Vue.prototype.$ajax = axios

4、 示例

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
axios.interceptors.request.use(
config => {
config.baseURL = '/api/'
config.withCredentials = true // 允许携带token ,这个是解决跨域产生的相关问题
config.timeout = 6000
let token = sessionStorage.getItem('access_token')
let csrf = store.getters.csrf
if (token) {
config.headers = {
'access-token': token,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
if (config.url === 'refresh') {
config.headers = {
'refresh-token': sessionStorage.getItem('refresh_token'),
'Content-Type': 'application/x-www-form-urlencoded'
}
}
return config
},
error => {
error.response // 返回的 响应体
return Promise.reject(error)
}
)


//在 response 拦截器实现
axios.interceptors.response.use(
response => {
// 定时刷新access-token
if (!response.data.value && response.data.data.message === 'token invalid') {
// 刷新token
store.dispatch('refresh').then(response => {
sessionStorage.setItem('access_token', response.data)
}).catch(error => {
throw new Error('token刷新' + error)
})
}
return response
},
error => {
error.response // 返回的 响应体
return Promise.reject(error)
}
)

5、返回 code 不是 200 时,

1
2
3
4
5
axios.interceptors.response.use(response => {
return response
}, error => {
error.response
})

这里的error.response返回的是一个对象, 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
// 服务器提供的响应
data: {},
// 服务器响应的HTTP状态代码
status: 200,
// 服务器响应的HTTP状态消息
statusText: 'OK',
// 服务器响应头
headers: {},
// axios 的配置
config: {}
}

示例

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
//main.js
axios.interceptors.request.use(function (config) {
iView.LoadingBar.start()
return config
}),function (error) {
iView.LoadingBar.error()
return Promise.reject(error)
}

axios.interceptors.response.use(function (config) {
iView.LoadingBar.finish()
return config
}),function (error) {
iView.LoadingBar.error()
return Promise.reject(error)
}

//a.js
import store from './vuex/store'
// 全局错误处理,全局loading
import { setLoading, setTip } from './vuex/actions/doc_actions'
export default function (request, next) {
if (request.tip !== false) {
setLoading(store, true)
}
next((res) => {
setLoading(store, false)
let data = JSON.parse(res.data)
if (res.status === 0) {
setTip(store, {
text: '网络不给力,请稍后再试'
})
}
if (!data.success) {
setTip(store, {
text: data.error_msg
})
}
})
}

Vue-resource

https://github.com/pagekit/Vue-resource/blob/master/docs/http.md

Vue-resource 是 Vue.js的一款插件,它可以通过 XMLHttpRequest 或 JSONP 发起请求并处理响应。也就是说,jquery的 $.ajax 能做的事情,Vue-resource 一样也能做到,而且 vue-resource 的API更为简洁。另外,Vue-resource还提供了非常有用的inteceptor功能,使用inteceptor可以在请求前和请求后附加一些行为,比如使用inteceptor在ajax请求时显示loading界面。

1、体积小。Vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比jQuery的体积要小得多。

2、支持主流的浏览器。和Vue.js一样,Vue-resource除了不支持IE 9以下的浏览器,其他主流的浏览器都支持。

3、支持Promise API和URI Templates。Promise是ES6的特性,Promise的中文含义为“先知”,Promise对象用于异步计算。URI Templates表示URI模板,有些类似于ASP.NET MVC的路由模板。

4、支持拦截器。拦截器是全局的,拦截器可以在请求发送前和发送请求后做一些处理。拦截器在一些场景下会非常有用,比如请求发送前在headers中设置access_token,或者在请求失败时,提供共通的处理方式。

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Vue.http.interceptors.push((request, next) => {
console.log(this)//此处this为请求所在页面的Vue实例
// modify request
request.method = 'POST';//在请求之前可以进行一些预处理和配置

// modify headers
request.headers.set('X-CSRF-TOKEN', 'TOKEN');
request.headers.set('Authorization', 'Bearer TOKEN');

// continue to next interceptor
next((response) => {//在响应之后传给then之前对response进行修改和逻辑判断。对于token时候已过期的判断,就添加在此处,页面中任何一次http请求都会先调用此处方法

response.body = '...';
return response;

});
});

Vue-resource 和 vue-axios 区别,

Vue-resource 和 Vue-axios 其实就是我们 Vue 请求里面的 this.$http.***this.axios.***

vue2.0 之后,Vue 官方就不再对 vue-resource 更新,而是推荐使用 axios。基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 Node.js 中使用。


Vue-resource 和 vue-axios 拦截器
https://flepeng.github.io/021-frontend-04-Vue-Vue-resource-和-vue-axios-拦截器/
作者
Lepeng
发布于
2021年8月11日
许可协议