更行了新得封裝,可以看下下面得第二種。。。。。
第一種:
項目本來是上傳一張pdf或者圖片,后來需求變化需要上傳多個文件,但是之前上傳使用的是轉換base64然后傳給后端,后端再去轉化。這種方式用于多文件的話由于轉換base64后體積過大,會造成請求時間過長,上傳時間過長等等問題。所以需要改造,上傳文件需換成文件流形式,需要換成FormData形式。由于項目所有post接口之前都定義為默認請求頭'application/x-www-form-urlencoded'
而FormData需要'multipart/form-data'。所以對項目封裝的axios進行了改造。并且不影響之前所有的post請求。代碼如下:
request.js代碼:
import axios from 'axios';
import qs from 'qs'
import cutModels from './option';
// 切換域名地址。
// todo: 配置全局域名訪問地址
// 默認可不填寫,默認值為official,official打包,dev本地測試,gray正式環境
window['cutModel'] = cutModels('dev');
//正式
axios.defaults.baseURL = cutModel.baseURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// axios.defaults.headers.post['Content-Type'] = 'multipart/form-data';
var instance = axios.create({
headers: {'content-type':'multipart/form-data'}
});
//http request 攔截器
axios.interceptors.request.use((config) => {
if(config.method === 'post'){
config.data = qs.stringify(config.data);
}
return config;
},(error) =>{
return Promise.reject(error);
});
/**
* 封裝get方法
* @param url
* @param data
* @returns {Promise}
*/
export function get(url,params={}){
return new Promise((resolve,reject) => {
axios.get(url,{
params:params
})
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err)
})
})
}
/**
* 封裝post請求
* @param url
* @param data
* @returns {Promise}
*/
export function post(url,data = {}){
return new Promise((resolve,reject) => {
axios.post(url,data)
.then(response => {
resolve(response.data);
},err => {
reject(err)
})
})
}
/**
* 封裝post請求 FormData方式
* @param url
* @param data
* @returns {Promise}
*/
export function postform(url,data = {}){
return new Promise((resolve,reject) => {
instance.post(url,data)
.then(response => {
resolve(response.data);
},err => {
reject(err)
})
})
}
main.js代碼引入
import Vue from 'vue'
import App from './App'
import router from './router'
import { get, post, postform } from './assets/js/request'
import { Loading, AlertModule } from 'vux'
Vue.component('loading', Loading)
Vue.prototype.$get = get;
Vue.prototype.$post = post;
Vue.prototype.$postform = postform;
Vue.config.productionTip = false
//路由守衛
router.beforeEach((to, from, next) => {
// next()
if(to.path == '/' || to.path == '/register') {
if(sessionStorage.getItem('userinfo')) {
AlertModule.show({
title: '提示',
content: "您已登錄!"
})
} else {
next()
}
} else {
//判斷是否有登錄用戶信息
if(sessionStorage.getItem('userinfo')) {
next()
} else {
AlertModule.show({
title: '提示',
content: "不好意思,您還未登錄!"
})
next({path:"/"})
}
}
});
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
頁面使用改造post方法
methods: {
//未改造之前的post請求方式,轉換成base64
toupload() {
// console.log(this.filesarr)
// console.log(this.filenamearr)
if (!this.option) {
AlertModule.show({
title: '提示',
content: '請選擇類型'
})
return false
}
if (!this.filesarr) {
AlertModule.show({
title: '提示',
content: '請上傳文件'
})
return false
}
this.showLoading = true
let self = this
// console.log(this.filesarr)
for(let i = 0; i< this.filesarr.length; i++) {
// 文件轉換 base64 編碼
this.blobToDataURL(this.filesarr[i]).then(res => {
self.fileUrlArr.push(res)
// 判斷遍歷完后上傳文件
if(self.fileUrlArr.length == this.filesarr.length) {
// console.log(self.fileUrlArr)
// 上傳文件
var userlogin = {
'ModuleName': 'UploadXCZL',
'TokenId': window['cutModel'].TokenId,
'RequestType': 'UploadData',
'Data':{
'User_Name': self.userinfo.UserName,
'Dept_Code': self.userinfo.Dept_Code, //部門編號
'Pcsh_Id': self.ShList.PKID, //批次收貨的編號
'PKID': self.continfo.PKID, //合同明細編號
'File_Type': self.option, //文件類型
'File_Name': self.filenamearr, //文件名
'File_Text': self.fileUrlArr, //文件的base64字符串
'Demo': self.bztext, //備注
}
}
self.$post('/xxxxxx', userlogin)
.then(res => {
self.showLoading = false
var res = JSON.parse(res)
// console.log(res);
if(res.Data.Statu_Code == 200) {
AlertModule.show({
title: '提示',
content: res.Data.Msg,
onHide () {
self.$router.push({
name: "stockdetails",
query: {
page: 0
}
});
}
})
} else if(res.Data.Statu_Code == 100) {
AlertModule.show({
title: '提示',
content: res.Data.Msg,
onHide () {
sessionStorage.clear()
self.$router.push('/')
}
})
} else {
AlertModule.show({
title: '不好意思',
content: res.Data.Msg
})
}
})
.catch(e => {
self.showLoading = false
AlertModule.show({
title: '不好意思',
content: '服務器繁忙'
})
});
}
})
}
},
//改造之后的post請求方式
loadto() {
this.showLoading = true
let self = this
let form = new FormData();
form.append("ModuleName",'UploadXCZL');
form.append("TokenId",window['cutModel'].TokenId);
form.append("RequestType",'UploadData');
form.append("Data['User_Name']",this.userinfo.UserName);
form.append("Data['Dept_Code']",this.userinfo.Dept_Code);
form.append("Data['Pcsh_Id']",this.ShList.PKID);
form.append("Data['PKID']",this.continfo.PKID);
form.append("Data['File_Type']",this.option);
form.append("Data['File_Name']",this.filenamearr);
form.append("Data['Demo']",this.bztext);
this.filesarr.forEach(function (file) {
form.append("Data['File_Text']", file);
})
for (var [a, b] of form.entries()) {
console.log(a, b);
}
this.$postform('/xxxxxxxx', form)
.then(res => {
this.showLoading = false
var res = JSON.parse(res)
console.log(res);
if(res.Data.Statu_Code == 200) {
AlertModule.show({
title: '提示',
content: res.Data.Msg,
onHide () {
this.$router.push({
name: "stockdetails",
query: {
page: 0
}
});
}
})
} else if(res.Data.Statu_Code == 100) {
AlertModule.show({
title: '提示',
content: res.Data.Msg,
onHide () {
sessionStorage.clear()
self.$router.push('/')
}
})
} else {
AlertModule.show({
title: '不好意思',
content: res.Data.Msg
})
}
})
.catch(e => {
this.showLoading = false
AlertModule.show({
title: '不好意思',
content: '服務器繁忙'
})
});
}
}
由于這個多文件是后面改的需求,如果整體項目換post請求,后端需要把所有接口改一遍,為了節省時間所以使用了這種方式,如果還有其他方式,歡迎大家留言交流
第二種:
后記,在看了一些大神得處理后,自己有重新封裝了一下這個請求。以前得那種封裝總覺得不是很合理。下面只是做了統一得封裝,不需要在去新實例化一個axios,效果還是不錯得。看代碼吧。
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// 創建一個AXIOS實例
const service = axios.create({
// baseURL: process.env.VUE_APP_BASE_API // url = base url + request url
// baseURL: 'xxxx' // 線上地址
// baseURL: 'xxxx' // 本地測試地址
baseURL: 'http://xxxxx' // 本地測試地址
// withCredentials: true, // send cookies when cross-domain requests
// timeout: 10000 // 請求超時
})
// 請求攔截器
service.interceptors.request.use(
config => {
// 在發出請求前做點什么
if (store.getters.token) {
// 讓每個請求攜帶令牌
// “X-Token”是自定義頭密鑰
// 請根據當前情況修改
config.headers['X-Token'] = getToken()
}
// 這里做了統一處理,多加了$_isFormData去判斷是什么樣得post請求
if (config.data && config.data.$_isFormData === false) {
config.headers['Content-Type'] = 'application/json'
// console.log(JSON.stringify(config.data.dataobj))
config.data = config.data.dataobj
} else {
config.headers['Content-Type'] = 'multipart/form-data'
}
// console.log(config)
return config
},
error => {
// 處理請求錯誤
console.log(error) // 用于調試
return Promise.reject(error)
}
)
// 響應攔截器
service.interceptors.response.use(
response => {
let res
if (typeof (response.data) === 'string') {
res = JSON.parse(response.data)
} else if (typeof (response.data) === 'object') {
res = response.data
}
if (res.Data.Statu_Code !== '200') {
// 403:令牌過期;
if (res.Data.Statu_Code === '403') {
// 重新登錄
MessageBox.confirm(res.Data.Msg, '確認注銷', {
confirmButtonText: '重新登錄',
// cancelButtonText: '取消',
showCancelButton: false,
showClose: false,
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
return Promise.reject(new Error(res.message || 'Error'))
} else if (res.Data.Statu_Code === '401') {
// 重新登錄
MessageBox.confirm(res.Data.Msg, '提示', {
confirmButtonText: '重新登錄',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
return Promise.reject(new Error(res.message || 'Error'))
} else {
Message({
message: res.Data.Msg || 'Error',
type: 'error',
duration: 2 * 1000,
offset: 100
})
return Promise.reject(new Error(res.message || 'Error'))
}
} else {
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 2 * 1000,
offset: 100
})
return Promise.reject(error)
}
)
export default service
在實際使用中可以這樣。兩種post請求。
import request from '@/utils/request'
export function procedureList(data) {
const { PageIndex, PageSize, Sort, Data } = data
const dataobj = {
moduleName: 'aaaaa',
requestType: 'aaa',
tokenId: 'aaaaaa',
PageIndex: PageIndex,
PageSize: PageSize,
Sort: Sort,
Data: Data
}
const postdata = { dataobj, $_isFormData: false }
return request({
url: 'aaaaaa',
method: 'post',
data: postdata
})
}
export function deleteMenu(data) {
const { ID } = data
const form = new FormData()
form.append('ModuleName', 'aaaaa')
form.append('TokenId', 'aaaaa')
form.append('RequestType', 'aaaaaa')
form.append('ID', ID)
return request({
url: 'MENU_DELBYID/MenuDelById',
method: 'post',
data: form
})
}
這樣要比之前更好處理。也更合理