一、问题描述
在前端使用
element-ui
进行文件上传时,需要携带请求头信息,比如Token
。
二、问题解决
1. 表单实现
action
置空- 添加
:http-request
属性覆盖默认的上传行为,实现自定义上传文件。 - 注意
:src
后的图片路径如果是个网络请求(外链),那么在前面拼接//
即可,否则会出现localhost:8080/外链
的奇葩问题。
html
<el-upload
class="avatar-uploader"
name="img"
action=""
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:http-request="handleUploadAvatar">
<img v-if="userInfoObj.avatar" :src="userInfoObj.avatar?'//'+userInfoObj.avatar:'static/img/tou.jpg'" :onerror="$store.state.errorImg" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
<div slot="tip" class="el-upload__tip">点击上传头像,只能上传jpg/png文件,且不超过1mb</div>
</el-upload>
2. js代码
- 创建
handleUploadAvatar()
函数,传入参数param
,其中的param
就是表单的文件对象。 - 创建
FormData
对象,封装请求体作为请求数据,将文件对象里面的文件以及需要携带的请求数据封装(比如需要携带id
信息等)进请求体。 - 创建
url
,即请求地址。 - 创建
config
对象,配置请求头信息,注意文件上传时,Content-Type
必须为multipart/form-data
。 - 使用
axios
发起post
请求。 - 注意此时
element-ui
组件上的:on-success="handleAvatarSuccess"
会不生效,因为禁用了action
这个默认实现方式 ,要想在上传文件成功后调用on-success
声明的函数,只需要手动调用一下即可。
js
<script>
import store from '../store'
import axios from 'axios'
import {getToken} from '../utils/auth.js'
export default {
name: 'UserInfo',
data() { //选项 / 数据
return {
uploadURL:'',
userInfo:{},
userInfoObj:'',
}
},
methods: {
beforeAvatarUpload(file) {// 上传头像成功前校验
const isJPG = file.type == 'image/png'||file.type=='image/jpg'||file.type=='image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 1;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG/JPEG/PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 1MB!');
}
return isJPG && isLt2M;
},
handleUploadAvatar(param) {
let fileObj = param.file // 相当于input里取得的files
let fd = new FormData()// FormData 对象
fd.append('img', fileObj)// 文件对象
let url = this.uploadURL
let config = {
headers: {
'Content-Type': 'multipart/form-data',
Token: getToken()
}
}
axios.post(url, fd, config).then(res => {
if(res.status === 200){
// 将服务端返回的数据传递给文件上传成功的函数
param.onSuccess(res.data)
}
})
},
handleAvatarSuccess(res, file) {// 上传头像成功后赋值
if(res.code == 200){
this.userInfoObj.avatar = res.data;
}else{
this.$message.error('上传图片失败');
}
}
},
created() {
this.uploadURL = store.state.baseURL + 'upload'
}
}
</script>