详解vue中axios请求的封装


Posted in Javascript onApril 08, 2019

axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中, 也是vue官方推荐使用的http库;封装axios,一方面为了以后维护方便,另一方面也可以对请求进行自定义处理

安装

npm i axios

封装

我把axios请求封装在http.js中,重新把get请求,post请求封装了一次

首先,引入axios

import axios from 'axios'

设置接口请求前缀

一般我们开发都会有开发、测试、生产环境,前缀需要加以区分,我们利用node环境变量来作判断,

if (process.env.NODE_ENV === 'development') {
 axios.defaults.baseURL = 'http://dev.xxx.com'
} else if (process.env.NODE_ENV === 'production') {
 axios.defaults.baseURL = 'http://prod.xxx.com'
}

在localhost调试时,直接用开发地址一般都会有跨域的问题,所以我们还需要配置代理

本项目是vue cli3搭建的,代理配置是在vue.config.js文件中:

module.exports = {
 devServer: {
 proxy: {
  '/proxyApi': {
  target: 'http://dev.xxx.com',
  changeOrigin: true,
  pathRewrite: {
   '/proxyApi': ''
  }
  }
 }
 }
}

这样就成功把/proxyApi 指向了 'http://dev.xxx.com',重启服务

修改一下http.js中的配置

if (process.env.NODE_ENV === 'development') {
 axios.defaults.baseURL = '/proxyApi'
} else if (process.env.NODE_ENV === 'production') {
 axios.defaults.baseURL = 'http://prod.xxx.com'
}

拦截器

接着设置超时时间和请求头信息

axios.defaults.timeout = 10000
// 请求头信息是为post请求设置
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'

axios很好用,其中之一就是它的拦截器十分强大,我们就可以为请求和响应设置拦截器,比如请求拦截器可以在每个请求里加上token,做了统一处理后维护起来也方便,响应拦截器可以在接收到响应后先做一层操作,如根据状态码判断登录状态、授权。

// 请求拦截器
axios.interceptors.request.use(
 config => {
 // 每次发送请求之前判断是否存在token
 // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的
 token && (config.headers.Authorization = token)
 return config
 },
 error => {
 return Promise.error(error)
 })
// 响应拦截器
axios.interceptors.response.use(response => {
 // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
 // 否则的话抛出错误
 if (response.status === 200) {
 if (response.data.code === 511) {
  // 未授权调取授权接口
 } else if (response.data.code === 510) {
  // 未登录跳转登录页
 } else {
  return Promise.resolve(response)
 }
 } else {
 return Promise.reject(response)
 }
}, error => {
 // 我们可以在这里对异常状态作统一处理
 if (error.response.status) {
 // 处理请求失败的情况
 // 对不同返回码对相应处理
 return Promise.reject(error.response)
 }
})

get post的封装

httpGet: 一个参数是请求的url,一个就携带的请求参数,返回promise对象

// get 请求
export function httpGet({
 url,
 params = {}
}) {
 return new Promise((resolve, reject) => {
 axios.get(url, {
  params
 }).then((res) => {
  resolve(res.data)
 }).catch(err => {
  reject(err)
 })
 })
}

httpPost: 原理和get差不多,需要注意,这里多了个data参数,post请求提交前需要对它进行序列号操作,这里是通过transformRequest做处理;另外两个参数url,params和get请求的一样;

// post请求
export function httpPost({
 url,
 data = {},
 params = {}
}) {
 return new Promise((resolve, reject) => {
 axios({
  url,
  method: 'post',
  transformRequest: [function (data) {
  let ret = ''
  for (let it in data) {
   ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
  }
  return ret
  }],
  // 发送的数据
  data,
  // url参数
  params

 }).then(res => {
  resolve(res.data)
 })
 })
}

如何使用

我把所有的接口调用都在api.js文件中

先引入封装好的方法,再在要调用的接口重新封装成一个方法暴露出去

import { httpGet, httpPost } from './http'
export const getorglist = (params = {}) => httpGet({ url: 'apps/api/org/list', params })

在页面中可以这样调用:

// .vue
import { getorglist } from '@/assets/js/api'

getorglist({ id: 200 }).then(res => {
 console.log(res)
})

这样可以把api统一管理起来,以后维护修改只需要在api.js文件操作即可。

完整代码
最后贴上完整代码

// http.js
import axios from 'axios'

// 环境的切换
if (process.env.NODE_ENV === 'development') {
 axios.defaults.baseURL = '/proxyApi'
} else if (process.env.NODE_ENV === 'production') {
 axios.defaults.baseURL = 'http://prod.xxx.com'
}

// 请求拦截器
axios.interceptors.request.use(
 config => {
 token && (config.headers.Authorization = token)
 return config
 },
 error => {
 return Promise.error(error)
 })

axios.defaults.timeout = 10000

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'

// 响应拦截器
axios.interceptors.response.use(response => {
 if (response.status === 200) {
 if (response.data.code === 511) {
  // 未授权调取授权接口
 } else if (response.data.code === 510) {
  // 未登录跳转登录页
 } else {
  return Promise.resolve(response)
 }
 } else {
 return Promise.reject(response)
 }
}, error => {
 // 我们可以在这里对异常状态作统一处理
 if (error.response.status) {
 // 处理请求失败的情况
 // 对不同返回码对相应处理
 return Promise.reject(error.response)
 }
})

// get 请求
export function httpGet({
 url,
 params = {}
}) {
 return new Promise((resolve, reject) => {
 axios.get(url, {
  params
 }).then((res) => {
  resolve(res.data)
 }).catch(err => {
  reject(err)
 })
 })
}

// post请求
export function httpPost({
 url,
 data = {},
 params = {}
}) {
 return new Promise((resolve, reject) => {
 axios({
  url,
  method: 'post',
  transformRequest: [function (data) {
  let ret = ''
  for (let it in data) {
   ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
  }
  return ret
  }],
  // 发送的数据
  data,
  // url参数
  params

 }).then(res => {
  resolve(res.data)
 })
 })
}
// api.js
import { httpGet, httpPost } from './http'
export const getorglist = (params = {}) => httpGet({ url: 'apps/api/org/list', params })

export const save = (data) => {
 return httpPost({
 url: 'apps/wechat/api/save_member',
 data
 })
}
// .vue
<script>
import { getorglist } from '@/assets/js/api'
export default {
 name: 'upload-card',
 data() {},
 mounted() {
 getorglist({ id: 200 }).then(res => {
  // console.log(res)
 })
 },
}
</script>

为什么还要多封装一层promise,不直接返回axios。
我在这里统一做个说明:
当然可以直接返回axios.get().then(res=>res.data),写法更简洁些;个人编程习惯,感觉resolve(res.data)写法更优雅些,这个就见仁见智了,所以正文对这点先做保留。这篇笔记也是提供一个思路,仅供参考。小伙伴可以根据自己实际业务需求来选择。

以上所述是小编给大家介绍的vue中axios请求的封装详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript高级程序设计 事件学习笔记
Sep 10 Javascript
javascript内存管理详细解析
Nov 11 Javascript
JS代码防止SQL注入的方法(超简单)
Apr 12 Javascript
jQuery简单注册和禁用全局事件的方法
Jul 25 Javascript
JS 对java返回的json格式的数据处理方法
Dec 05 Javascript
解析js如何获取css样式
Dec 11 Javascript
js放大镜放大购物图片效果
Jan 18 Javascript
angular2 ng2 @input和@output理解及示例
Oct 10 Javascript
Layui实现数据表格中鼠标悬浮图片放大效果,离开时恢复原图的方法
Sep 11 Javascript
在react中使用vue的状态管理的方法示例
May 02 Javascript
vue+axios全局添加请求头和参数操作
Jul 24 Javascript
在vue中使用inheritAttrs实现组件的扩展性介绍
Dec 07 Vue.js
使用taro开发微信小程序遇到的坑总结
Apr 08 #Javascript
vue+element+Java实现批量删除功能
Apr 08 #Javascript
如何为你的JavaScript代码日志着色详解
Apr 08 #Javascript
详解element-ui日期时间选择器的日期格式化问题
Apr 08 #Javascript
小程序获取当前位置加搜索附近热门小区及商区的方法
Apr 08 #Javascript
服务端预渲染之Nuxt(使用篇)
Apr 08 #Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
Apr 08 #Javascript
You might like
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(八)
2014/06/23 PHP
PHP使用array_multisort对多个数组或多维数组进行排序
2014/12/16 PHP
10个对初学者非常有用的PHP技巧
2016/04/06 PHP
让你的PHP7更快之Hugepage用法分析
2016/05/31 PHP
PHP基于DOM创建xml文档的方法示例
2017/02/08 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
2019/03/12 PHP
禁止刷新,回退的JS
2006/11/25 Javascript
jquery1.4 教程二 ajax方法的改进
2010/02/25 Javascript
jquery 表格分页等操作实现代码(pagedown,pageup)
2010/04/11 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
JavaScript编程中实现对象封装特性的实例讲解
2016/06/24 Javascript
underscore之function_动力节点Java学院整理
2017/07/11 Javascript
微信小程序之GET请求的实例详解
2017/09/29 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
vue-cli如何引入bootstrap工具的方法
2017/10/19 Javascript
Nodejs中crypto模块的安全知识讲解
2018/01/03 NodeJs
jQuery的ztree仿windows文件新建和拖拽功能的实现代码
2018/12/05 jQuery
ionic使用angularjs表单验证(模板验证)
2018/12/12 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
jquery实现简单拖拽效果
2020/07/20 jQuery
python学习之matplotlib绘制散点图实例
2017/12/09 Python
django加载本地html的方法
2018/05/27 Python
Django添加feeds功能的示例
2018/08/07 Python
python控制nao机器人身体动作实例详解
2019/04/29 Python
python实现小世界网络生成
2019/11/21 Python
Python如何使用argparse模块处理命令行参数
2019/12/11 Python
解决Python pip 自动更新升级失败的问题
2020/02/21 Python
python GUI库图形界面开发之PyQt5表单布局控件QFormLayout详细使用方法与实例
2020/03/06 Python
python实现同一局域网下传输图片
2020/03/20 Python
Django-Scrapy生成后端json接口的方法示例
2020/10/06 Python
Django ModelForm组件原理及用法详解
2020/10/12 Python
离婚协议书怎么写2014
2014/09/30 职场文书
教师师德工作总结2015
2015/07/22 职场文书
python爬虫--selenium模块
2021/03/31 Python
CSS3 制作精美的定价表
2021/04/06 HTML / CSS