VueJS 2搭配Strapi使用axios上传文件报404错误
文件上传功能失效&404报错修复方案
现存问题
- 提交按钮位于
<form>标签内但未指定type="button",默认是submit类型,加上外层包裹的<a>标签,点击时会触发原生表单提交+页面跳转,直接向8080端口的当前路径发请求,完全绕过了你写的axios上传逻辑,这是404报错的直接原因 - FormData构造错误,你传入的是文件名字符串,不是真实的File文件对象,后端无法接收到实际的CV文件
- 删除文件逻辑不完整,只清空了显示的文件名,没有清空已存储的文件对象和文件输入框的选中状态
- 没有等待上传接口返回结果就跳转,会导致上传请求被中途中断
- 空的catch块会吞掉报错信息,出问题时无法快速定位原因
修正代码
模板部分(template)
移除包裹提交按钮的a标签,给按钮加type="button"阻止表单默认提交,给form加提交拦截,修改后对应代码:
<template> <div> <div class="send-background"> <form @submit.prevent> <div class="send-form-child"> <h3>{{jobinfos.position}}</h3> <div class="line"> <h6>Upload CV:</h6> <div class="up-cv"> <button for="real-file" @click="onFileChange" type="button" id="custom-button" > 选择文件 </button> <input id="real-file" type="file" accept=".pdf,.doc,.docx" style="display: none" @change="fileName" name="image" /> <div class="name-cv"> <h5 v-if="uploadedFileName" id="custom-text"> {{ uploadedFileName }} </h5> <h5 v-else id="custom-text">Bạn chưa chọn file</h5> <img v-if="uploadedFileName" @click="deleteFile" src="../../assets/recruit/delete.svg" alt="删除文件" /> </div> </div> </div> <button @click="submitFile" class="btn-send" type="button">Submit</button> </div> </form> </div> </div> </template>
脚本部分(script)
修正文件上传、删除逻辑,等上传成功后再执行页面跳转,补充错误提示:
<script> import axios from 'axios' export default { props: { id: String, }, data() { return { uploadedFileName: null, fileCV: null, jobinfos: [], }; }, mounted() { this.getdetail(); }, methods: { onFileChange() { document.getElementById("real-file").click(); }, fileName(e) { const selectedFile = e.target.files[0] if (!selectedFile) return this.uploadedFileName = selectedFile.name; this.fileCV = selectedFile }, deleteFile() { this.uploadedFileName = null; this.fileCV = null // 清空文件输入框残留值 document.getElementById("real-file").value = '' }, async submitFile(){ // 上传前校验是否选择了文件 if (!this.fileCV) { alert('Vui lòng chọn file CV trước khi nộp') return } const formData = new FormData(); // 传入真实文件对象,不是文件名字符串 formData.append('files', this.fileCV); try { const res = await axios.post('http://localhost:1337/upload/', formData) // 上传成功后再跳转页面 if (res.status === 200) { // 如果用vue-router就用路由跳转,普通页面跳转用window.location window.location.href = './succes.html' } } catch (e) { console.error('CV上传失败:', e) alert('Tải lên CV thất bại, vui lòng thử lại') } }, async getdetail() { try { const id = this.$route.params.id; const response = await axios.get(`http://localhost:1337/jobinfos/` + id) this.jobinfos = response.data; } catch (e) { console.error('获取职位详情失败:', e) } }, }, }; </script>
补充说明
- 你用的1337端口是Strapi的默认服务端口,文件上传成功后会返回文件的唯一id,后续提交职位申请时需要把这个id和对应的职位、用户信息关联,不要只上传文件不关联业务数据
- 文件选择框加了
accept属性限制可上传的文件格式,避免用户选错文件 - 不要手动给上传请求设置
Content-Type请求头,让浏览器自动生成带boundary边界参数的multipart/form-data头,否则后端会解析文件失败
内容的提问来源于stack exchange,提问作者BinChanhKun
相关产品推荐
相关产品推荐

