VUE 数据请求和响应(axios)
1. 概述
1.1 简介
axios是一个基于Promise(本机支持ES6 Promise实现) 的HTTP库,用于浏览器和 nodejs 的 HTTP 客户端。具有以下特征:
-
- 从浏览器中创建 XMLHttpRequests
- XMLHttpRequest对象用于在后台与服务器交换数据,可做到在不重新加载页面的情况下更新网页,在页面已加载后从服务器请求数据或接收数据,在后台向服务器发送数据。所有的浏览器都支持XMLHttpRequest对象。
- 从 node.js 创建 http 请求
- 如get/post等
- 支持 Promise API
- 如promise所支持的链式回调,.then(res => {}).catch(err =>{})
- 拦截请求和响应
- 在请求之前或响应之后进行的处理,如请求之前增加统一的token标识,响应之后对公用的错误进行处理等。
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF
- 从浏览器中创建 XMLHttpRequests
1.2 引入使用
npm install axios 进行安装,安装成功后 import axios from 'axios' 进行引入模块,再对axios对象进行设置。如
/** * 创建axios对象 **/ let axiosInstance =axios.create({ baseURL: configHttp.domain, withCredentials:true, });
备注:使用 Vue.prototype.$http = axios; 进行配置于vue项目中,在页面中可使用this.$http.get('xxxx').then().catch()。
1.3 常用请求配置
1.3.1 url
数据请求的服务器URL,此配置必须存在,否则无访问路径无法进行数据请求。
1.3.2 method
创建请求时使用的方法,默认get方式。有多种请求方式,如:request/get/delete/head/post/put/patch,常用get与post.
1.3.3 baseURL
设置一个统一的基础路径(如http://www.demo.com/api/),使axios的get或post中的url使用相对URL,更改访问域名或端口号时只更改对应的baseURL值即可。
1.3.4 headers
headers是即将被发送的自定义请求头,可设置请求的数据标识(token)或post请求的数据类型等。
1.3.5 timeout
请求超时时间,单位为毫秒,若超过超时时间则请求中断。0表示无超时时间。
1.3.6 withCredentials
跨域请求时是否需要使用凭证,默认为false
1.4 配置的默认与自定义实例
优先级别为:自定义实例>全局默认值>自带默认值
1.全局默认值
axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
2.自定义实例
// 创建实例时设置配置的默认值 var instance = axios.create({ baseURL: 'https://api.example.com' }); // 在实例已创建后修改默认值 instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
备注:也可在请求拦截中进行设置对应的配置。
1.5 拦截器
在请求或响应被 then 或 catch 处理前拦截他们,分为请求拦截器和响应拦截器;
-
- 请求拦截器(interceptors.request)是指可以拦截每次或指定HTTP请求,并可修改配置项。
- 响应拦截器()可以拦截每次HTTP请求对应的响应,并可修改返回结果项。
示意图:
一般在请求拦截器中增加标识token或其他请求配置,在响应拦截器中对统一错误或状态码进行处理(跳转统一页面如登录)
// 添加请求拦截器 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); });
2. 实例
2.1 axios配置
备注:在headers.post['Content-Type']不为application/json时,传递post参数时需使用querystring中的querystring.stringify对参数进行格式化处理。
import axios from 'axios' import configHttp from '../../configHttp' /** * 创建axios对象 **/ let axiosInstance =axios.create({ baseURL: configHttp.domain, withCredentials:true, }); /** * 访问请求拦截(在请求前处理) **/ axiosInstance.interceptors.request.use( function (config) { config.headers.common['Platform'] = 'web'; return config; }, function (error) { return Promise.reject(error) } ); /** * 响应请求拦截(在响应前处理) **/ axiosInstance.interceptors.response.use( function (response) { return response; }, function (error) { if(error.response){ let status=error.response.status; switch (status) { case 401: // 跳转至login break; } } //处理报错 记录日志 if (error !== undefined) { console.log(error); } } ); /** * http请求响应处理函数 **/ let httpResponseHandle = function(){ let self = this; let res = self.res; if (res.code == '0') { self.successCallback && self.successCallback(res); } else if (res.code == 'C00004' || res.code =='C00002') { // 清除token // 跳转至login } else { // 统一错误弹出 self.failCallback && self.failCallback(res); } }; let http= { /** * 以get方式请求获取JSON数据 * @param {Object} opts 配置项,可以包含以下成员: * @param {String} opts.url 请求地址 * @param {Object} opts.params 附加的请求参数 * @param {Function} opts.successCallback 成功的回调函数 * @param {Function} opts.failCallback 失败的回调函数 * **/ get: function (opts) { axiosInstance .get(opts.url, {params: opts.params}) .then(function (res) { opts.res = res.data; httpResponseHandle.call(opts); }) .catch(function (err) { if (err.response) { if (err.response.data) { opts.res = err.response.data; httpResponseHandle.call(opts); } else { // 统一错误弹出 } } }); }, /** * 以post方式请求获取JSON数据 * @param {Object} opts 配置项,可以包含以下成员: * @param {String} opts.url 请求地址 * @param {Object} opts.params 附加的请求参数 * @param {Function} opts.successCallback 成功的回调函数 * @param {Function} opts.failCallback 失败的回调函数 * **/ post: function (opts) { axiosInstance .post(opts.url, opts.params) .then(function (res) { opts.res = res.data; httpResponseHandle.call(opts); }) .catch(function (err) { if (err.response) { if (err.response.data) { opts.res = err.response.data; httpResponseHandle.call(opts); } else { // 统一错误弹出 } } }); } }; export default http;
2.2 实例调用
在Vue中使用prototype进行设置,不能使用use设置。
1.main.js中直接写入
import http from '@/common/js/http.js';
Vue.prototype.$http = http;
2.其他引入
import Vue from 'vue' import axios from '../common/js/http.js' Vue.prototype.$http = axios
2.3 页面使用
vue单页面中的methods中使用
1.get示例
this.$http.get({ url: 'comm/getDataInfo', params: { param1: xxx, param2: '3' }, successCallback: res => { // 数据处理 }, failCallback: res => {} });
2.post示例
this.$http.post({ url: 'common/userLogin', params: { username: 'admin', password: '123456' }, successCallback: res => { // 数据处理 }, failCallback: res => {} });
2.4 http请求Content-Type: application/x-www-form-urlencoded
接口使用x-www-form-urlencoded格式接收/传递数据时,需要使用qs(原来的querystring)对所传递的参数进行格式化处理;
1.设置数据格式
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
2.在请求拦截处统一处理参数格式化
config.data = qs.stringify(config.data)
import axios from 'axios' import qs from 'qs' const http = axios.create({ timeout: 15000, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }) /** * 请求拦截器 */ http.interceptors.request.use(config => { const objParams = { appKey: 'ccc', bizContent: JSON.stringify(config.data), } config.data = qs.stringify(objParams) // objParams为传递参数 return config }, error => { Promise.reject(error) })