1. Axios简介
1.1 什么是Axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
1.2 特性
- 浏览器端发起XMLHttpRequests请求
- node端发起http请求
- 支持Promise API
- 监听请求和返回
- 转化请求和返回
- 取消请求
- 自动转化json数据
- 客户端支持抵御
2. Axios的使用和配置
2.1 安装
1
| npm install axios --save
|
或者使用cdn
1
| <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
2.2 基本使用
2.2.1 Get请求
1 2 3 4 5 6 7 8 9
| axios.get('/user', { params: { name: 'krislin' } }).then(function (response) { console.log(response); }).catch(function (error) { console.log(error) }
|
2.2.2 Post请求
1 2 3 4 5 6 7 8 9 10
| axios.post('/user',{ name:'krislin', address:'china' }) .then(function(response){ console.log(response); }) .catch(function(error){ console.log(error); });
|
2.2.3 并发操作
1 2 3 4 5 6 7 8 9 10 11 12
| function getUserAccount(){ return axios.get('/user/12345'); }
function getUserPermissions(){ return axios.get('/user/12345/permissions'); }
axios.all([getUerAccount(),getUserPermissions()]) .then(axios.spread(function(acc,pers){ }));
|
2.3 请求API配置
axios 能够在进行请求时进行一些设置,具体如下:
1 2 3 4 5 6 7 8
| axios({ method:'post', url:'/user/12345', data:{ name:'krislin', address:'china' } });
|
2.4 请求设置
请求配置中,只有url是必须的,如果没有指明的话,默认是Get请求
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| { url:'/user', method:`get`, baseURL:'http://some-domain.com/api/', transformRequest:[function(data){ return data; }], transformResponse:[function(data){ return data; }], headers:{'X-Requested-with':'XMLHttpRequest'}, params:{ ID:12345 }, paramsSerializer: function(params){ return Qs.stringify(params,{arrayFormat:'brackets'}) }, data:{ firstName:'fred' }, timeout:1000, withCredentials:false adapter:function(config){ }, auth:{ username:'janedoe', password:'s00pers3cret' }, responsetype:'json', xrsfHeadername:'X-XSRF-TOKEN', onUploadProgress: function(progressEvent){ }, onDownloadProgress: function(progressEvent){ }, maxContentLength: 2000, validateStatus: function(status){ return status >= 200 && stauts < 300; }, httpAgent: new http.Agent({keepAlive:treu}), httpsAgent: new https.Agent({keepAlive:true}), proxy:{ host:127.0.0.1, port:9000, auth:{ username:'cdd', password:'123456' } }, cancelToke: new CancelToken(function(cancel){ }) }
|
2.5 响应数据Response
一个请求的返回包含以下信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { data{}, status:200, statusText: 'ok', headers:{}, config:{} }
|
2.6 拦截器Interceptors
你可以在 请求 或者 返回 被 then 或者 catch 处理之前对他们进行拦截。
添加拦截器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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); });
|
移除拦截器:
1 2
| var myInterceptor = axios.interceptors.request.use(function(){}); axios.interceptors.rquest.eject(myInterceptor);
|
3. 跨域
因为在Vue的开发阶段,基本都是用webpack打包编译,需要node环境本地运行,因而运行的域名为本地的localhost,这个时候调用后端接口就涉及到跨域的问题了。
3.1 ProxyTable
vue 的 proxyTable 是用于开发阶段配置跨域的工具,可以同时配置多个后台服务器跨越请求接口,其真正依赖的npm包是 http-proxy-middleware, 在GitHub上拥有更丰富的配置,可以按需配置
在不考虑后端CROS跨域方案的情况下,前端配置ProxyTable实现跨域请求的用法如下:
1. 找到 config/index.js 文件中的 proxyTable:{} 将其修改
1 2 3 4 5 6 7 8 9
| proxyTable: { '/api': { target: 'https://tasst.sinoxk.cn', changeOrigin: true, pathRewrite: { '^/api': '' } } }
|
proxyTable支持配置多个接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| proxyTable: { '/api': { target: 'https://tasst.sinoxk.cn', changeOrigin: true, pathRewrite: { '^/api': '' } }, '/service': { target: 'https://tasst.sinoxk.cn', changeOrigin: true, pathRewrite: { '^/service': '' } } }
|
2. 找到 config/dev.env.js 文件,配置BASE_URL
1 2 3 4
| module.exports = merge(prodEnv, { NODE_ENV: '"development"', BASE_URL:'"/api"' })
|
3. 找到 config/prod.env.js 文件,配置BASE_URL
1 2 3 4
| module.exports = { NODE_ENV: '"production"', BASE_URL:'"https://asst.sinoxk.com"' }
|
4. 配置 axios 的基础域名
1
| axios.defaults.baseURL = process.env.BASE_URL
|
修改完所有的配置文件后,要注意,需要重启下环境
1
| npm run dev / npm run start
|
4. 封装
在日常项目开发过程中,在和后台交互获取数据的时候,我们都需要使用到网络库,通常在vue的项目中 ,使用的是 axios 库 ,在此基于自身项目业务,做一个二次封装。
4.1 条件准备
在UI轻提示组件上,选定的是 vant 库中的 Toast 组件(Vant文档),可按实际需要选定具体要使用的UI框架
安装:
数据序列化,如果有实际需要的项目,可以使用qs,在这里做一个简单的介绍
安装:
qs.stringify和JSON.stringify的使用和区别
qs.stringify()将对象 序列化成URL的形式,以&进行拼接
JSON.stringify 是将对象转化成一个json字符串的形式
用法:
1 2 3 4 5
| var a = {name:'xiaoming',age:10}
qs.stringify(a);
JSON.stringify(a)
|
基于底层配置和业务接口分离,在src目录中会新建文件夹 httpServer,同时新建立 ajax.js 和 api.js 文件
1
| ajax.js: axios的二次封装,作为基础网络库,添加基础的配置
|
1
| api.js: 管理项目实际业务基础接口的输出,以及返回响应数据的处理
|
在日常项目模块中,基于多人开发,当然可以在api.js的基础上,可以根据功能模块实现业务拓展延伸,比如
1 2 3 4 5 6 7 8 9 10 11 12
| 小明负责list模块业务
新建api-list.js,并导入api.js ....
import api from './api'
export default { getList(url,params){ api.get(url,params) } }
|
对于个别项目,可能存在多个域名配置的情况下, 可以重新建立 base.js , 来管理多个接口域名
base.js:
1 2 3 4 5 6 7 8 9
|
const base = { sq: 'https://xxxx111111.com/api/v1', bd: 'http://xxxxx22222.com/api' }
export default base;
|
4.2 axios封装(单域名)
src/main.js文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import Vue from 'vue' import App from './App' import router from './router' import Api from './httpServer/api'
Vue.prototype.$https = Api
Vue.config.productionTip = false
new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
|
src/httpServer/ajax.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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import axios from 'axios' import {Toast} from 'vant'
const ajax = axios.create({ timeout:60000, baseURL:process.env.BASE_URL })
ajax.interceptors.request.use( config => { return config; }, error => Promise.error(error) )
ajax.interceptors.response.use( res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res), error => { const {response} = error; if (response) { Toast({message: response.message}); return Promise.reject(response); } else { Toast({message: '网络开小差,请稍后重试'}); } } )
export default ajax;
|
对于process.env.BASE_URL的配置,在开发环境中,需要以代理的方式进行访问:
1 2 3 4 5 6 7 8 9 10
|
'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, { NODE_ENV: '"development"', BASE_URL:'"/api"' })
|
1 2 3 4 5 6 7
|
'use strict' module.exports = { NODE_ENV: '"production"', BASE_URL:'"https://www.xxx.com"' }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| ...
proxyTable: { '/api': { target: 'https://tasst.sinoxk.cn', changeOrigin: true, pathRewrite: { '^/api': '', }, } }, ...
|
src/httpServer/api.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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import ajax from './ajax' import {Toast} from 'vant'
const handleResponse = (res, success, failure) => { switch (res.code) { case 200: success && success(res.data); break; case 401:
break; default: if (failure) { failure(res); } else { Toast({message:res.msg || '请求失败,请稍后重试!'}); } break; } }
export default { get: function (url, params, success, failure) { ajax.get(url, { params: params }).then(res => { if (res.status == 200) { handleResponse(res.data.data, success, failure); } }); },
post: function (url, params, success, failure) { ajax.post(url, params).then(res => { if (res.status == 200) { handleResponse(res.data.data, success, failure); } }) } }
|
在src/components/HelloWorld.vue文件中使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <script> export default { name: 'HelloWorld', data() { return { msg: 'Welcome to Your Vue.js App' } }, created() { this.$https.get('/xkzx/member/service', { pageNum: 1, pageSize: 10 }, function (data) { console.log(data);
}, function (res) {
})
} } </script>
|