文章目录
- 一. 总体代码流程
- 1.1 全局Axios部分样例
- 1.2 上传业务
- 二. 后端部分
- 三. 测试样例
go的mvc层使用gin框架. 总的来说gin的formFile封装的不如springboot的好.获取值有很多的坑. 当然使用axios的formData也有不少坑.现给出较好的解决办法
以下部分仅贴出关键代码
一. 总体代码流程
1.1 全局Axios部分样例
axios前后端网络交互
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: 'http://127.0.0.1:20139',
// 超时
timeout: 5000
})
export default service;
// 不使用service实例.重新创建axios封装上传
export function uploadFiles(url,data={}){
return axios({
method: "POST",
url: 'http://127.0.0.1:20139'+url,
transformRequest: [function(data, headers) {
// 去除post请求默认的Content-Type
delete headers['Content-Type']
return data
}],
data: data,
})
}
1.2 上传业务
关键代码一览.需要留意的是,我使用手动上传,element中before-upload,before-remove失效. 为避免更多问题使用了on-change监听.其中uploadFile参数是element封装的普通对象. file对象被封装在其中的raw属性. 这一点要尤为注意 gin框架不同于springboot. formfile只能读取file类型
<el-form :inline="true"
:model="resumeForm"
class="demo-form-inline"
label-position="right"
label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="姓名">
<el-input v-model="resumeForm.name" placeholder="请输入姓名" clearable/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="电话">
<el-input v-model="resumeForm.phone" placeholder="请输入电话" clearable/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="邮箱">
<el-input v-model="resumeForm.email" placeholder="请输入邮箱" clearable/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="工作经验">
<el-input v-model="resumeForm.experience" placeholder="请输入工作经验" clearable/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="学历">
<el-select
v-model="resumeForm.education"
placeholder="请选择学历水平"
clearable
>
<el-option label="专科" value="0"/>
<el-option label="本科" value="1"/>
<el-option label="研究生" value="2"/>
<el-option label="博士" value="3"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="上传简历">
<el-upload
ref="recruitRef"
class="upload-demo"
drag
action="#"
:auto-upload="false"
:on-change="handleChange"
limit="1"
>
<el-icon class="el-icon--upload">
<upload-filled/>
</el-icon>
<div class="el-upload__text">
拖拽 或 <em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip">
.pdf 文件大小 ≤ 500kb
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="postResumeForm()">投递</el-button>
</el-form-item>
</el-form>
const router = useRouter()
const resumeForm = reactive({
name: '',
phone: '',
email: '',
experience: '',
education: '',
position: router.currentRoute.value.params.position
})
const recruitRef = ref()
let formData = new FormData()
// 文件改变触发
function handleChange(uploadFile, uploadFiles) {
// 文件校验
if (!verifyBeforeUpload(uploadFile)) {
removeFile()
return
}
console.log(uploadFile)
formData.append("file", uploadFile.raw)
}
function removeFile() {
if (recruitRef.value) {
formData = new FormData()
recruitRef.value.clearFiles()
}
}
// 提交表单
function postResumeForm() {
ElMessageBox.confirm('确认提交?提交后仅能修改一次', '提示', {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
if (formData === null || formData === undefined) {
ElMessage.info("必须递交简历信息!")
return
}
for (let key in resumeForm) {
formData.append(key,resumeForm[key])
}
let res = await reqPostResumeForm(formData)
if (res.code !== 200) {
ElMessage.error("简历投递失败")
return
}
await ElMessageBox.alert("简历投递成功! 3-7个工作日内,您将收到回复", '提示', {
confirmButtonText: "确认"
})
removeFile()
}).catch((err) => {
removeFile()
console.log(err)
ElMessage.info("简历投递已取消!")
})
}
文件校验部分
// 单文件大小校验
function verifyFileSize(file) {
if (file) {
let fileSize = file.size;
let fileMaxSize = 1024 * 500;//500kb
if (fileSize > fileMaxSize) {
ElMessage.error("文件不能大于500kb!");
file.value = "";
return false;
} else if (fileSize <= 0) {
ElMessage.error("文件不能为0kb!");
file.value = "";
return false;
}
return true
}
ElMessage.error("必须传递文件!")
return false;
}
// 校验文件格式和大小
export function verifyBeforeUpload(file) {
// 格式
const extension = file.name.split('.').pop().toLowerCase();
console.log(extension)
if (!ACCEPTED_EXTENSIONS.includes(extension)) {
ElMessage.error('仅支持 pdf 格式的文件');
return false;
}
// 大小
return verifyFileSize(file);
}
请求发送部分
export function reqPostResumeForm(formData){
return uploadFiles(jobs.postResumeUrl,formData)
}
二. 后端部分
func PostResume(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
panic(fmt.Sprintf("file参数不能为空"))
}
var resume model.Resume
err = c.ShouldBind(&resume)
if err != nil {
panic(fmt.Sprintf("resume获取错误,原因是: %v", err))
}
log.Printf("%v", file)
}
三. 测试样例