vue axios封装两种post请求方式

た 入场券 2023-01-17 07:32 580阅读 0赞

第一种:

项目本来是上传一张pdf或者图片,后来需求变化需要上传多个文件,但是之前上传使用的是转换base64然后传给后端,后端再去转化。这种方式用于多文件的话由于转换base64后体积过大,会造成请求时间过长,上传时间过长等等问题。所以需要改造,上传文件需换成文件流形式,需要换成FormData形式。由于项目所有post接口之前都定义为默认请求头’application/x-www-form-urlencoded’
而FormData需要’multipart/form-data’。所以对项目封装的axios进行了改造。并且不影响之前所有的post请求。代码如下:
request.js代码:

  1. import axios from 'axios';
  2. import qs from 'qs'
  3. import cutModels from './option';
  4. // 切换域名地址。
  5. // todo: 配置全局域名访问地址
  6. // 默认可不填写,默认值为official,official打包,dev本地测试,gray正式环境
  7. window['cutModel'] = cutModels('dev');
  8. //正式
  9. axios.defaults.baseURL = cutModel.baseURL;
  10. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
  11. // axios.defaults.headers.post['Content-Type'] = 'multipart/form-data';
  12. var instance = axios.create({
  13. headers: {'content-type':'multipart/form-data'}
  14. });
  15. //http request 拦截器
  16. axios.interceptors.request.use((config) => {
  17. if(config.method === 'post'){
  18. config.data = qs.stringify(config.data);
  19. }
  20. return config;
  21. },(error) =>{
  22. return Promise.reject(error);
  23. });
  24. /**
  25. * 封装get方法
  26. * @param url
  27. * @param data
  28. * @returns {Promise}
  29. */
  30. export function get(url,params={}){
  31. return new Promise((resolve,reject) => {
  32. axios.get(url,{
  33. params:params
  34. })
  35. .then(response => {
  36. resolve(response.data);
  37. })
  38. .catch(err => {
  39. reject(err)
  40. })
  41. })
  42. }
  43. /**
  44. * 封装post请求
  45. * @param url
  46. * @param data
  47. * @returns {Promise}
  48. */
  49. export function post(url,data = {}){
  50. return new Promise((resolve,reject) => {
  51. axios.post(url,data)
  52. .then(response => {
  53. resolve(response.data);
  54. },err => {
  55. reject(err)
  56. })
  57. })
  58. }
  59. /**
  60. * 封装post请求 FormData方式
  61. * @param url
  62. * @param data
  63. * @returns {Promise}
  64. */
  65. export function postform(url,data = {}){
  66. return new Promise((resolve,reject) => {
  67. instance.post(url,data)
  68. .then(response => {
  69. resolve(response.data);
  70. },err => {
  71. reject(err)
  72. })
  73. })
  74. }

main.js代码引入

  1. import Vue from 'vue'
  2. import App from './App'
  3. import router from './router'
  4. import { get, post, postform } from './assets/js/request'
  5. import { Loading, AlertModule } from 'vux'
  6. Vue.component('loading', Loading)
  7. Vue.prototype.$get = get;
  8. Vue.prototype.$post = post;
  9. Vue.prototype.$postform = postform;
  10. Vue.config.productionTip = false
  11. //路由守卫
  12. router.beforeEach((to, from, next) => {
  13. // next()
  14. if(to.path == '/' || to.path == '/register') {
  15. if(sessionStorage.getItem('userinfo')) {
  16. AlertModule.show({
  17. title: '提示',
  18. content: "您已登录!"
  19. })
  20. } else {
  21. next()
  22. }
  23. } else {
  24. //判断是否有登录用户信息
  25. if(sessionStorage.getItem('userinfo')) {
  26. next()
  27. } else {
  28. AlertModule.show({
  29. title: '提示',
  30. content: "不好意思,您还未登录!"
  31. })
  32. next({path:"/"})
  33. }
  34. }
  35. });
  36. /* eslint-disable no-new */
  37. new Vue({
  38. el: '#app',
  39. router,
  40. components: { App },
  41. template: '<App/>'
  42. })

页面使用改造post方法

  1. methods: {
  2. //未改造之前的post请求方式,转换成base64
  3. toupload() {
  4. // console.log(this.filesarr)
  5. // console.log(this.filenamearr)
  6. if (!this.option) {
  7. AlertModule.show({
  8. title: '提示',
  9. content: '请选择类型'
  10. })
  11. return false
  12. }
  13. if (!this.filesarr) {
  14. AlertModule.show({
  15. title: '提示',
  16. content: '请上传文件'
  17. })
  18. return false
  19. }
  20. this.showLoading = true
  21. let self = this
  22. // console.log(this.filesarr)
  23. for(let i = 0; i< this.filesarr.length; i++) {
  24. // 文件转换 base64 编码
  25. this.blobToDataURL(this.filesarr[i]).then(res => {
  26. self.fileUrlArr.push(res)
  27. // 判断遍历完后上传文件
  28. if(self.fileUrlArr.length == this.filesarr.length) {
  29. // console.log(self.fileUrlArr)
  30. // 上传文件
  31. var userlogin = {
  32. 'ModuleName': 'UploadXCZL',
  33. 'TokenId': window['cutModel'].TokenId,
  34. 'RequestType': 'UploadData',
  35. 'Data':{
  36. 'User_Name': self.userinfo.UserName,
  37. 'Dept_Code': self.userinfo.Dept_Code, //部门编号
  38. 'Pcsh_Id': self.ShList.PKID, //批次收货的编号
  39. 'PKID': self.continfo.PKID, //合同明细编号
  40. 'File_Type': self.option, //文件类型
  41. 'File_Name': self.filenamearr, //文件名
  42. 'File_Text': self.fileUrlArr, //文件的base64字符串
  43. 'Demo': self.bztext, //备注
  44. }
  45. }
  46. self.$post('/xxxxxx', userlogin)
  47. .then(res => {
  48. self.showLoading = false
  49. var res = JSON.parse(res)
  50. // console.log(res);
  51. if(res.Data.Statu_Code == 200) {
  52. AlertModule.show({
  53. title: '提示',
  54. content: res.Data.Msg,
  55. onHide () {
  56. self.$router.push({
  57. name: "stockdetails",
  58. query: {
  59. page: 0
  60. }
  61. });
  62. }
  63. })
  64. } else if(res.Data.Statu_Code == 100) {
  65. AlertModule.show({
  66. title: '提示',
  67. content: res.Data.Msg,
  68. onHide () {
  69. sessionStorage.clear()
  70. self.$router.push('/')
  71. }
  72. })
  73. } else {
  74. AlertModule.show({
  75. title: '不好意思',
  76. content: res.Data.Msg
  77. })
  78. }
  79. })
  80. .catch(e => {
  81. self.showLoading = false
  82. AlertModule.show({
  83. title: '不好意思',
  84. content: '服务器繁忙'
  85. })
  86. });
  87. }
  88. })
  89. }
  90. },
  91. //改造之后的post请求方式
  92. loadto() {
  93. this.showLoading = true
  94. let self = this
  95. let form = new FormData();
  96. form.append("ModuleName",'UploadXCZL');
  97. form.append("TokenId",window['cutModel'].TokenId);
  98. form.append("RequestType",'UploadData');
  99. form.append("Data['User_Name']",this.userinfo.UserName);
  100. form.append("Data['Dept_Code']",this.userinfo.Dept_Code);
  101. form.append("Data['Pcsh_Id']",this.ShList.PKID);
  102. form.append("Data['PKID']",this.continfo.PKID);
  103. form.append("Data['File_Type']",this.option);
  104. form.append("Data['File_Name']",this.filenamearr);
  105. form.append("Data['Demo']",this.bztext);
  106. this.filesarr.forEach(function (file) {
  107. form.append("Data['File_Text']", file);
  108. })
  109. for (var [a, b] of form.entries()) {
  110. console.log(a, b);
  111. }
  112. this.$postform('/xxxxxxxx', form)
  113. .then(res => {
  114. this.showLoading = false
  115. var res = JSON.parse(res)
  116. console.log(res);
  117. if(res.Data.Statu_Code == 200) {
  118. AlertModule.show({
  119. title: '提示',
  120. content: res.Data.Msg,
  121. onHide () {
  122. this.$router.push({
  123. name: "stockdetails",
  124. query: {
  125. page: 0
  126. }
  127. });
  128. }
  129. })
  130. } else if(res.Data.Statu_Code == 100) {
  131. AlertModule.show({
  132. title: '提示',
  133. content: res.Data.Msg,
  134. onHide () {
  135. sessionStorage.clear()
  136. self.$router.push('/')
  137. }
  138. })
  139. } else {
  140. AlertModule.show({
  141. title: '不好意思',
  142. content: res.Data.Msg
  143. })
  144. }
  145. })
  146. .catch(e => {
  147. this.showLoading = false
  148. AlertModule.show({
  149. title: '不好意思',
  150. content: '服务器繁忙'
  151. })
  152. });
  153. }
  154. }

由于这个多文件是后面改的需求,如果整体项目换post请求,后端需要把所有接口改一遍,为了节省时间所以使用了这种方式,如果还有其他方式,欢迎大家留言交流

第二种:

后记,在看了一些大神得处理后,自己有重新封装了一下这个请求。以前得那种封装总觉得不是很合理。下面只是做了统一得封装,不需要在去新实例化一个axios,效果还是不错得。看代码吧。

  1. import axios from 'axios'
  2. import { MessageBox, Message } from 'element-ui'
  3. import store from '@/store'
  4. import { getToken } from '@/utils/auth'
  5. // 创建一个AXIOS实例
  6. const service = axios.create({
  7. // baseURL: process.env.VUE_APP_BASE_API // url = base url + request url
  8. // baseURL: 'xxxx' // 线上地址
  9. // baseURL: 'xxxx' // 本地测试地址
  10. baseURL: 'http://xxxxx' // 本地测试地址
  11. // withCredentials: true, // send cookies when cross-domain requests
  12. // timeout: 10000 // 请求超时
  13. })
  14. // 请求拦截器
  15. service.interceptors.request.use(
  16. config => {
  17. // 在发出请求前做点什么
  18. if (store.getters.token) {
  19. // 让每个请求携带令牌
  20. // “X-Token”是自定义头密钥
  21. // 请根据当前情况修改
  22. config.headers['X-Token'] = getToken()
  23. }
  24. // 这里做了统一处理,多加了$_isFormData去判断是什么样得post请求
  25. if (config.data && config.data.$_isFormData === false) {
  26. config.headers['Content-Type'] = 'application/json'
  27. // console.log(JSON.stringify(config.data.dataobj))
  28. config.data = config.data.dataobj
  29. } else {
  30. config.headers['Content-Type'] = 'multipart/form-data'
  31. }
  32. // console.log(config)
  33. return config
  34. },
  35. error => {
  36. // 处理请求错误
  37. console.log(error) // 用于调试
  38. return Promise.reject(error)
  39. }
  40. )
  41. // 响应拦截器
  42. service.interceptors.response.use(
  43. response => {
  44. let res
  45. if (typeof (response.data) === 'string') {
  46. res = JSON.parse(response.data)
  47. } else if (typeof (response.data) === 'object') {
  48. res = response.data
  49. }
  50. if (res.Data.Statu_Code !== '200') {
  51. // 403:令牌过期;
  52. if (res.Data.Statu_Code === '403') {
  53. // 重新登录
  54. MessageBox.confirm(res.Data.Msg, '确认注销', {
  55. confirmButtonText: '重新登录',
  56. // cancelButtonText: '取消',
  57. showCancelButton: false,
  58. showClose: false,
  59. type: 'warning'
  60. }).then(() => {
  61. store.dispatch('user/resetToken').then(() => {
  62. location.reload()
  63. })
  64. })
  65. return Promise.reject(new Error(res.message || 'Error'))
  66. } else if (res.Data.Statu_Code === '401') {
  67. // 重新登录
  68. MessageBox.confirm(res.Data.Msg, '提示', {
  69. confirmButtonText: '重新登录',
  70. cancelButtonText: '取消',
  71. type: 'warning'
  72. }).then(() => {
  73. store.dispatch('user/resetToken').then(() => {
  74. location.reload()
  75. })
  76. })
  77. return Promise.reject(new Error(res.message || 'Error'))
  78. } else {
  79. Message({
  80. message: res.Data.Msg || 'Error',
  81. type: 'error',
  82. duration: 2 * 1000,
  83. offset: 100
  84. })
  85. return Promise.reject(new Error(res.message || 'Error'))
  86. }
  87. } else {
  88. return res
  89. }
  90. },
  91. error => {
  92. console.log('err' + error) // for debug
  93. Message({
  94. message: error.message,
  95. type: 'error',
  96. duration: 2 * 1000,
  97. offset: 100
  98. })
  99. return Promise.reject(error)
  100. }
  101. )
  102. export default service

在实际使用中可以这样。两种post请求。

  1. import request from '@/utils/request'
  2. export function procedureList(data) {
  3. const { PageIndex, PageSize, Sort, Data } = data
  4. const dataobj = {
  5. moduleName: 'aaaaa',
  6. requestType: 'aaa',
  7. tokenId: 'aaaaaa',
  8. PageIndex: PageIndex,
  9. PageSize: PageSize,
  10. Sort: Sort,
  11. Data: Data
  12. }
  13. const postdata = { dataobj, $_isFormData: false }
  14. return request({
  15. url: 'aaaaaa',
  16. method: 'post',
  17. data: postdata
  18. })
  19. }
  20. export function deleteMenu(data) {
  21. const { ID } = data
  22. const form = new FormData()
  23. form.append('ModuleName', 'aaaaa')
  24. form.append('TokenId', 'aaaaa')
  25. form.append('RequestType', 'aaaaaa')
  26. form.append('ID', ID)
  27. return request({
  28. url: 'MENU_DELBYID/MenuDelById',
  29. method: 'post',
  30. data: form
  31. })
  32. }

这样要比之前更好处理。也更合理

发表评论

表情:
评论列表 (有 0 条评论,580人围观)

还没有评论,来说两句吧...

相关阅读

    相关 vue-封装axios请求

    最近接手新的vue项目,发现axios竟然没有封装,立马动手封装,这里记录一下完整的封装过程,废话不说,直接上代码 baseConfig.js文件 //存放各个服