拦截器简介
顾名思义,拦截器主要是拦截,放到 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'
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 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) } )
axios.interceptors.response.use( response => { if (!response.data.value && response.data.data.message === 'token invalid') { 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: {}, status: 200, statusText: 'OK', headers: {}, 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
| 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) }
import store from './vuex/store'
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) request.method = 'POST'; request.headers.set('X-CSRF-TOKEN', 'TOKEN'); request.headers.set('Authorization', 'Bearer TOKEN'); next((response) => {
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 中使用。