You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:57:27