记录下项目中遇到的图片上传,亦或者文件上传的方式,总是遗忘,查资料好慢
项目采用的vue-element-admin 使用vue/vuex/vue-router/element-ui技术开发
由于request.js封装的接口类型,都是基于普通接口的请求,没有封装文件上传的接口类型
request.js代码如下
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import { getToken, removeToken, removeUserMenu, removeUserId } from '@/utils/auth'
import router from '@/router/index'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API + '/' + process.env.VUE_APP_API_VERSION,
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['authorization'] = 'Bearer ' + getToken()
}
// console.log(config)
const tthash = window.btoa(
window
.btoa(encodeURI(location.hash.replace('#/', '') ?? ''))
.split('')
.reverse()
.join('')
)
if (config.method == 'post') {
config.data = {
...config.data,
ttname: location.pathname.replace('/', ''),
tthash: tthash,
tenantCode: process.env.NODE_ENV === 'development' ? process.env.VUE_APP_TENANT_CODE : '',
productCode: process.env.NODE_ENV === 'development' ? process.env.VUE_APP_PRODUCT_CODE : ''
}
} else if (config.method == 'get') {
config.params = {
...config.params,
ttname: location.pathname.replace('/', ''),
tthash: tthash
}
}
return config
},
error => {
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
response => {
const { code, message } = response.data
// 返回正常结果
if (code == 10000) return response.data
Message({
message: message || 'Error',
type: 'warning',
duration: 1.5 * 1000
})
return Promise.reject(response.data)
},
error => {
if (error.response && error.response.status == 401) {
removeToken()
removeUserMenu()
removeUserId()
// store.dispatch('user/logout', store.getters.userId)
Message({
message: error.message,
type: 'error',
duration: 1.5 * 1000
})
router.push({ path: '/login' })
} else if (error.response && error.response.status == 403) {
Message({
message: error.message,
type: 'error',
duration: 1.5 * 1000
})
router.push({ path: '/403' })
}
return Promise.reject(error.data || {})
}
)
export default service
以上代码可以看出,文件上传接口不在此列,所以文件上传接口需要单独编写
编写的时候需要注意,请求的一些参数,请求头,都需要另外拿出来放到文件上传接口中
下面来主要说一下,文件上传写法,采用了,element-ui中的el-upload组件,代码如下
<el-form-item label="LOGO" prop="logo">
<el-upload
class="avatar-uploader"
action="#"
:show-file-list="false"
accept="image/*"
:http-request="upload"
>
<img :src="from.logo" class="avatar" />
</el-upload>
</el-form-item>
*action --上传的地址,必选
*show-file-list --是否显示已上传文件列表
*accept --接受上传的文件类型,这里image/*是指图片格式的
*:http-request --覆盖默认的上传行为,可以自定义上传的实现,这里使用这个,上面action可以忽略
然后我们这里使用了:http-request="upload"自定义的方式,那么下面就来看看这种方式实现,
代码如下:
import axios from 'axios'
import { getToken } from '@/utils/auth'
// 上传图片
upload(e) {
//这是参数配置,可以忽略
const tthash = window.btoa(
window
.btoa(encodeURI(location.hash.replace('#/', '') ?? ''))
.split('')
.reverse()
.join('')
)
//使用FormData 的最大优点就是可以异步上传二进制文件。
//而图片,文件之类的文件是二进制,接口接收参数也是接收的二进制
//可以先通过new关键字创建一个空的 FormData 对象,然后使用 append() 方法向该对象里添加字段
//(字段的值可以是一个 Blob 对象,File对象或者字符串,剩下其他类型的值都会被自动转换成字符串)。
//也可以用一个已有的form元素来初始化FormData对象
const formData = new FormData()
//这里是把上传接口所有的参数都append到formData中
formData.append('img', e.file)
formData.append('type', 'market')
formData.append('ttname', location.pathname.replace('/', ''))
formData.append('tthash', tthash)
formData.append('tenantCode', process.env.NODE_ENV === 'development' ? process.env.VUE_APP_TENANT_CODE : '')
formData.append('productCode', process.env.NODE_ENV === 'development' ? process.env.VUE_APP_PRODUCT_CODE : '')
const config = {
headers: {
'Content-Type': 'multipart/form-data',
'authorization': 'Bearer ' + getToken()
}
}
//接口调用
axios.post('/api/tenant/assist/upload_image', formData, config).then((res) => {
this.from.logo = res.data.data.filename
})
},
//使用方法
upload(e) {
this.getBase64(e.file).then((res) => {
console.log(res)
})
}
//图片文件转base64方法
getBase64(file) {
return new Promise(function(resolve, reject) {
const reader = new FileReader()
let imgResult = ''
reader.readAsDataURL(file)
reader.onload = function() {
imgResult = reader.result
}
reader.onerror = function(error) {
reject(error)
}
reader.onloadend = function() {
resolve(imgResult)
}
})
},
方法注释,都写到了代码注释中,细看就能看明白
后续会持续更新








网友评论