axios请求封装与开发环境proxyTable代理详解

  • 一、axios请求封装
    • 1. axios安装与使用
      • 1.1 安装
      • 1.2 引入
      • 1.3 环境切换
      • 1.4 设置请求超时
      • 1.5 请求头设置
      • 1.6 请求拦截
      • 1.7 响应拦截
      • 1.8 使用方法
    • 2. axios二次封装
      • 2.1 封装方法
      • 3.2 使用方法
  • 二、开发环境proxyTable代理详解
    • 1. proxyTable原理概述
    • 2. 使用方法

一、axios请求封装

1. axios安装与使用

1.1 安装

 npm install axios; // 安装axios

1.2 引入

在项目中 axios 的封装一般都放在 src 目录下的 utils 文件夹中,因此我们在此处新建一个 request.js 文件用来封装我们的 axios 请求。先贴代码:

/****   request.js   ****/
// 导入axios
import axios from 'axios'
// 使用element-ui Message做消息提醒
import { Message} from 'element-ui';
// 1. 创建新的axios实例,
const service = axios.create({// 公共接口--这里注意后面会讲baseURL: process.env.BASE_API,// 超时时间 单位是ms,这里设置了3s的超时时间timeout: 3 * 1000
})
// 2.请求拦截器
service.interceptors.request.use(config => {// 发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换config.headers = {'Content-Type':'application/x-www-form-urlencoded' //配置请求头}// 注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookieconst token = getCookie('名称'); //这里取token之前,你肯定需要先拿到token,存一下if(token){config.params = {'token':token} //如果要求携带在参数中config.headers.token = token; //如果要求携带在请求头中}return config
}, error => {Promise.reject(error)
})// 3.响应拦截器
service.interceptors.response.use(res => {// 未设置状态码则默认成功状态const code = res.data.code || 200;// 获取错误信息const msg = errorCode[code] || res.data.msg || errorCode['default']if (msg == 401 ) {MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {store.dispatch('LogOut').then(() => {location.href = '/';})}).catch(() => {});} else if (code === 500) {Message({message: msg,type: 'error'})return Promise.reject(new Error(msg))} else if (code !== 200) {Notification.error({title: msg})return Promise.reject('error')} else {return res.data}},error => {console.log('err' + error)let { message } = error;if (message == "Network Error") {message = "后端接口连接异常";}else if (message.includes("timeout")) {message = "系统接口请求超时";}else if (message.includes("Request failed with status code")) {message = "系统接口" + message.substr(message.length - 3) + "异常";}Message({message: message,type: 'error',duration: 5 * 1000})return Promise.reject(error)}
)
// 4.导出文件
export default service

1.3 环境切换

我们的项目环境可能有开发环境、测试环境和生产环境。我么可以通过node的环境变量来匹配我们的默认的接口url前缀。
在这里要注意的是 axios.defaults.baseURL 可以设置 axios 的默认请求地址。

// 设置baseURL方法一:外部设置
if (process.env.NODE_ENV == 'development') {    axios.defaults.baseURL = 'https://www.baidu.com';}
else if (process.env.NODE_ENV == 'production') {    axios.defaults.baseURL = 'https://www.production.com';
}
// 设置baseURL方法二:实例内设置
const service = axios.create({// baseURL: process.env.NODE_ENV == 'development' ? 'https://www.baidu.com' : 'https://www.production.com'timeout: 3 * 1000
})
// 以上两种方法是等价的,任选一种都可以

1.4 设置请求超时

通过axios.defaults.timeout设置默认的请求超时时间。

1.5 请求头设置

由于post请求时需要加上内容的数据类型,因此需要加上请求头配置

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

1.6 请求拦截

我们在发送请求前可以进行请求拦截。当系统需要登录时,在这里可以判断 token 的状态,若存在则将 token 加入请求头中。

service.interceptors.request.use(config => {//发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换config.headers = {'Content-Type':'application/json;charset=UTF-8' //配置请求头}//注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookieconst token = getCookie('名称');//这里取token之前,你肯定需要先拿到token,存一下if(token){config.params = {'token':token} //如果要求携带在参数中config.headers.token= token; //如果要求携带在请求头中}return config
}, error => {Promise.reject(error)
})

1.7 响应拦截

响应拦截器就是当服务器返回给我们的数据,我们可以在拿到之前对它进行一些处理。例如,当状态码为除 200 外的其他码时则根据状态码类型进行一些我们需要的错误提示,我们还可以在这里对执行未登陆或登录过期后跳转登录页的操作。

service.interceptors.response.use(res => {// 未设置状态码则默认成功状态const code = res.data.code || 200;// 获取错误信息const msg = errorCode[code] || res.data.msg || errorCode['default']if (msg == 401 ) {MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {store.dispatch('LogOut').then(() => {location.href = '/';})}).catch(() => {});} else if (code === 500) {Message({message: msg,type: 'error'})return Promise.reject(new Error(msg))} else if (code !== 200) {Notification.error({title: msg})return Promise.reject('error')} else {return res.data}},error => {console.log('err' + error)let { message } = error;if (message == "Network Error") {message = "后端接口连接异常";}else if (message.includes("timeout")) {message = "系统接口请求超时";}else if (message.includes("Request failed with status code")) {message = "系统接口" + message.substr(message.length - 3) + "异常";}Message({message: message,type: 'error',duration: 5 * 1000})return Promise.reject(error)}
)

1.8 使用方法

请求方法都会放在 src 目录下的 api 文件夹中统一管理。当项目规模较小时直接创建一个 api.js,将所有的请求放在其中即可,当项目规模较大时可根据模块和功能进行划分,将请求置于多个文件内进行管理。

/****     api.js     ****/
import request from '@/utils/request'// 获取验证码图片
export function getCodeImg() {return request({url: '/auditms/captchaImage',method: 'get'})
}// 登录方法
export function login(data) {return request({url: '/auditms/api/account/login',method: 'post',data: data})
}

2. axios二次封装

我们常用的请求方式有 getpostputdelete,尤其是 getpost,相信大家一定都不陌生,axios 也有响应的方法。当项目请求数量比较多时我们可将 axios 进行二次封装

2.1 封装方法

axios 的二次封装也放在 src 目录下的 utils 文件夹中,我们在此处新建一个http.js 的文件。代码如下:

/****     http.js     ****/
import request from './request.js'const http = {/*** methods: 请求* @param url 请求地址 * @param params 请求参数*/get(url, params) {const config = {method: 'get',url: url,}if(params)config.params = params;return request(config)},post(url, params) {const config = {method: 'post',url: url,}if(params) config.data = params;return request(config)},put(url, params) {const config = {method: 'put',url: url,}if(params)config.params = params;return request(config)},delete(url, params) {const config = {method: 'delete',url: url,}if(params)config.params = params;return request(config)}
}export default http

3.2 使用方法

封装后按如下格式即可使用。

/****     api.js     ****/
import http from '@/utils/http'// 获取步骤条
export function getStepTitle() {return http.get(`/deploy/separate/stepTitle`)
}// 上传网络配置信息
export function netWorkMgr(params) {return http.post(`/deploy/separate/netWorkMgr`, params)
}

二、开发环境proxyTable代理详解

前面讲完 axios 的安装、封装和使用,后面就讲讲项目前后端分离时开发环境如何解决跨域问题

1. proxyTable原理概述

我们在使用 vue-cli 工具生成 vue 项目时,生成的项目里有一个 config 文件夹,里面会有一个 index.js
文件。文件内容如下,老规矩,与文章无关的内容先省略。

'use strict'
const path = require('path')module.exports = {// 开发相关配置dev: {// PathsassetsSubDirectory: 'static', //子目录,一般存放css,js,image等文件assetsPublicPath: '/', //根目录proxyTable: {},// 省略部分内容},// 与编译相关的配置build: {// 省略}
}

其中的 proxyTable 空节点是 vue-cli 脚手架在开发模式下为我们提供的一个代理服务器服务

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域,但由于项目前后端分离,现在开发过程中跨域是无可避免的。

proxyTable 的核心就是将服务器端(另一个域)代理到开发环境的域,也就是将服务器端代理到开发环境的node站点。

也正因如此,我们用F12查看网络时,请求的URl就是当前页面的URL,因为我们代理的结果就是发送到开发环境(也就是当前环境)的node站点。

2. 使用方法

讲完了 proxyTable 的原理,接下来就讲讲它的使用。

首先,使用 proxyTable 跨域有三个文件需要注意,这三个文件分别是 src -> api -> api.js(查看请求URL)、src -> utils -> request.js(查看axios的baseURL配置)和 config -> index.js

以上面的获取验证码请求为例:

export function getCodeImg() {return request({url: '/auditms/captchaImage',method: 'get'})
}

请求的url为 /auditms/captchaImage

再看 request.js 中的baseURL配置:

const service = axios.create({// axios中请求配置有baseURL选项,表示请求URL公共部分// baseURL: process.env.BASE_API,// 超时timeout: 10000,
})

baseURL 未曾配置,也就是说此时请求地址为 /auditms/captchaImage

此处需注意:若这两个URL拼接起来后是一个带有协议、域名、端口号的绝对地址或是请求中的URL直接就是绝对地址那么该请求就不会走 proxyTable 代理。

最后,我们再仔细看看 config -> index.js 文件中的 proxyTable 节点配置。

proxyTable: { //可利用该属性解决跨域的问题// 1、匹配请求'/auditms': {// 2、服务地址target: 'http://127.0.0.1:3000',// 3、证书安全// secure: true, //如果是 https ,需要开启这个选项changeOrigin: true, //是否是跨域请求?肯定是啊,不跨域就没有必要配置这个proxyTable了.// 4、路径重写pathRewrite: {'^/auditms': '/auditms',}},
},

我们要关注的第一个地方是匹配规则,也就是上面代码中的第三行:'/auditms:',这个地方就是请求进行匹配的地方,匹配上的请求会被转发到对应的服务。而请求匹配的规则就一点:先到先得

'/aaa/bb': {target: 'xxx',prependPath: true,changeOrigin: true,secure: false},'/aaa/bb/cccccc': {target: 'xxx',prependPath: true,changeOrigin: true,secure: false},

假设设置了以上两个代理,当请求URL为 /aaa/bb/ccccc/dd 时,请求会被第一个代理转发到相应的服务上,哪怕后面的更为精确。
因此,我们在写匹配规则的时候要将最严格的匹配模式放在最前面,将不严格的方式放在后面。

我们要关注的第二个地方就是服务地址,匹配上的请求会发往相应的服务地址,如上面的验证码请求就将被发往 http://127.0.0.1:3000/auditms/captchaImage

我们要关注的第三个地方是 secure 配置,当服务地址的协议为 https 时需要开启此选项。我在项目开发时因为将此项设置为 secure: true,花了我半天的时间才找到问题所在,但我并不了解其中原理,若以后大家确定自己其他地方都已配置正确时可更改此项为 secure: false 试试。

终于到最后一点啦,路径重写,顾名思义,就是将前面匹配的路径进行重写。如前面的例子中就是将 /auditms 重写为 /auditms ,有的人可能会想,这不是啥也没做吗?没错,此处就是啥也没做,这种情况下就可以将 pathRewrite 配置注释掉。

pathRewrite: {'^/auditms': '/auditms',
}

如果一个项目中出现多个后端服务地址时我们就会用到此配置,通过设置不同的URL前缀来控制请求发往不同的服务,当我们在请求URL前加入了语义化的前缀时也可通过设置值为空串来删掉无用的URL前缀。

终于写完啦,下班回家咯,希望这篇文章能对大家有所帮助。不卷了,溜了溜了。

axios请求封装与开发环境proxyTable代理相关推荐

  1. vue-webpack项目本地开发环境设置代理解决跨域问题

    vue-webpack项目本地开发环境设置代理解决跨域问题 参考文章: (1)vue-webpack项目本地开发环境设置代理解决跨域问题 (2)https://www.cnblogs.com/xyyt ...

  2. vue-cli2.x统一配置接口请求地址和开发环境的跨域代理

    1.修改config/dev.env.js(开发环境的baseURL地址统一配置) 2.修改config/prod.env.js(线上环境的baseURL地址统一配置) 3.修改config/inde ...

  3. Vue3+Vite+TS后台项目 ~ 4. axios请求封装

    一.axios封装 1. request 请求封装 新建 src / utils / request.ts 文件: import axios from 'axios'const request = a ...

  4. 小程序仿 axios 请求封装

    一.新建request.js /** 功能:小程序仿 axios 的请求封装*/ export default class Request {// 配置项configure = {baseURL: ' ...

  5. axios请求封装(带拦截器)

    请求封装二(带拦截器) //请求 import service from '../utils/requst' export function hlserver(){return new Promise ...

  6. vue-cli3通过不同命令打包文件到不同文件夹并配置不同请求地址(开发环境、UAT环境、生产环境)

    一.区分不同环境 1.在根目录下新建3个文件(.env.development..env.production..env.uat)文件类型为.txt文件 .env.development VUE_AP ...

  7. vscode中为golang开发环境配置代理goproxy

    和 npm . pip 等包管理工具一样,你的包都是从网上拉去到本地,然而,由于国内网络的原因,这些工具 你都得换国内代理,要不然下载很慢或直接失败. 这篇文章所讲的 为golang开发下载插件(开发 ...

  8. html中使用js将axios请求封装

    百度中全是vue-cli中使用axios的方式,我需要用的是在html中引入axios.js 1.新建 httpRequest.js 文件,定义如下方法: //axios封装post请求 functi ...

  9. 工作119:axios请求封装

    /*封装系统需要的post请求 第一个参数传入url地址 第二个传入数据参数*/ export function postAction(url, parameter) {return axios({u ...

最新文章

  1. libsvm Minist Hog 手写体识别
  2. stdthread(6)并发lockGuard
  3. redis可以存多少条数据_最新数据!在武汉14区排名多少可以上高中?精准定位...
  4. 今日发现的:一个类似Google Baidu的搜索引擎[C#]代码比较简单
  5. springboot创建多个对象
  6. EIGRP路由协议的数据库
  7. 数模笔记_多变量最优化计算之随机搜索算法及建模案例
  8. 架构师成长之路(内附推荐书籍)
  9. 转载—android 媒体库数据更新解决办法总结
  10. “RuntimeError: main thread is not in main loop“的几种解决方案
  11. Linux命令解释之chmod
  12. Linux的cat命令详解
  13. win7下安装openSSH
  14. 2021安徽安全员B证考试多选练习题库
  15. springboot自定义Servlet容器
  16. 探索性因子分析和验证性因子分析有什么区别?
  17. 电商挖角潮起:工作两年百万年薪
  18. 100行Python代码,做一个打地鼠小游戏!
  19. 解决 libpng warning: iCCP: known incorrect sRGB profile
  20. vb.net 教程 5-9 屏幕范围内取色

热门文章

  1. 解决windows电脑系统图片不显示缩略图预览的2种办法
  2. 小米手机linux自动化测试,【自动化测试怎么样】小米2021年自动化测试前景怎么样-看准网...
  3. Word、Excel、PowerPoint一直闪屏怎么办?
  4. 安装vue3.0脚手架
  5. 自助式BI分析有哪些优势?
  6. java 运行jar包命令_用java –jar 命令运行Jar包
  7. 线稿图视频制作--从此短视频平台不缺上传视频了
  8. fgo日服封科技_FGO国服B站阴兵刷活动?鬼王血条急速消失,他们才是罪魁祸首...
  9. Redis面试题-Redis集群Twemproxy与Codis
  10. 荣耀猎人是鸿蒙,四百即可享受游戏加速 荣耀猎人游戏路由上手:游戏利器