??????712 2024-11-03 11:48 采纳率: 70%
浏览 14
已结题

前端vue无法访问正确url,无法正确上传图片

我在后端写了个获取用户提交反馈的功能,后端的/feedbacks可以正常使用,但是在前端vue中却提示无法访问这个url,点击上传图片按钮就提示如下两个图片错误

img

img

img

下面是前端vue


<template>
  <div>
    <el-form @submit.prevent="submitFeedbackForm">
      <el-form-item label="反馈的类型">
        <el-select style="width: 270px;" v-model="feedbackForm.leixing" placeholder="请选择类型">
          <el-option label="好评" value="0"></el-option>
          <el-option label="建议" value="1"></el-option>
          <el-option label="差评" value="2"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="问题/建议">
        <el-input style="width: 270px;" v-model="feedbackForm.nr" type="textarea"></el-input>
      </el-form-item>

      <el-form-item label="重要程度">
        <el-slider
            style="width: 270px;"
            v-model="feedbackForm.qiangdu"
            :min="1"
            :max="10"
            :marks="marks"
            show-stops
            show-tooltip
        ></el-slider>
      </el-form-item>

      <el-form-item label="上传图片(最多三张)">
        <el-upload
            style="width: 270px;"
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            :before-remove="beforeRemove"
            :on-change="handleFileChange"
            multiple
            :limit="3"
            :on-exceed="handleExceed"
            :file-list="fileList"
        >
          <el-button size="small" type="primary">点击上传</el-button>
          <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过3张</div>
        </el-upload>
      </el-form-item>

      <el-form-item style="margin-top: 50px;">
        <el-button type="primary" @click="submitFeedbackForm">提交反馈</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import {ref} from 'vue';
import {ElMessage} from 'element-plus';
import {fetchFeedbackList} from '@/api/feedbacks';

const feedbackForm = ref({
  nr: '', // 内容
  leixing: '', // 类型
  qiangdu: 5, // 强度,默认为5
  liulanqi: '', // 浏览器类型
});
feedbackForm.value.liulanqi = navigator.userAgent;

const marks = {
  1: '可以接受',
  10: '无法接受',
};

const fileList = ref([]);

const handlePreview = (file) => {
  console.log(file);
};

const handleRemove = (file, fileList) => {
  console.log(file, fileList);
};

const beforeRemove = (file, fileList) => {
  return confirm(`确定移除 ${file.name}?`);
};

const handleExceed = (files, fileList) => {
  ElMessage.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
};

// 处理文件变更,将文件保存到 feedbackForm 中
const handleFileChange = (file, fileList) => {
  feedbackForm.value.files = fileList.map(f => f.raw);
};

const submitFeedbackForm = async () => {
  try {
    const formData = new FormData();
    formData.append('leixing', feedbackForm.value.leixing);
    formData.append('nr', feedbackForm.value.nr);
    formData.append('qiangdu', feedbackForm.value.qiangdu);
    formData.append('liulanqi', feedbackForm.value.liulanqi);

    // 添加文件到 FormData
    if (feedbackForm.value.files && feedbackForm.value.files.length > 0) {
      feedbackForm.value.files.forEach(file => {
        formData.append('image', file);
      });
    }

    // 发送请求
    const response = await fetchFeedbackList(formData);

    // 检查服务器响应是否包含 data 属性,并且 status 为 true
    if (response && response.data && response.data.status === true) {
      // 清空表单或进行其他操作
      feedbackForm.value.nr = '';
      feedbackForm.value.leixing = '';
      feedbackForm.value.qiangdu = 5;
      fileList.value = [];
    } else {
      ElMessage.success(response?.data?.message || '提交成功,感谢您的反馈');
    }
  } catch (error) {
    // 如果发生异常(例如网络错误),则捕获异常并显示错误消息
    console.error('提交反馈时发生错误:', error); // 打印错误信息,以便调试
    ElMessage.error('提交反馈失败,请确认所有信息全部填写完成');
  }
};
</script>

下面是前端的路由,/router/index.js


import { createRouter, createWebHistory } from 'vue-router'
import Layouts from "../views/layouts/IndexView.vue";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/login",
      component: () => import("../views/auth/LoginView.vue"),
    },
    {
      path: "/register",
      component: () => import("../views/auth/RegisterView.vue"),
    },
    {
      path: "/resetting",
      component: () => import("../views/auth/ResettingView.vue"),
    },
    {
      path: "/",
      component: Layouts,
      children: [
        {
          path: "",
          component: () => import("../views/articles/ListView.vue"),
        },
        {

          path: "/articles/show1/:id",
          component: () => import("../views/articles/Show1View.vue"),
        },

          {
              path: "/articles/show2/:id",
              component: () => import("../views/articles/Show2View.vue"),
          },
          {
              path: "/articles/show/:id",
              component: () => import("../views/articles/ShowView.vue"),
          },




        {
          path: "/no2",
          component: () => import("../views/articles/ListView1.vue"),
        },

        {
          path: "/no3",
          component: () => import("../views/articles/ListView2.vue"),
        },



        {
          path: "/users/account",
          component: () => import("../views/users/AccountView.vue"),
        },
        {
          path: "/users/info",
          component: () => import("../views/users/InfoView.vue"),
        },

        {
          path: "/feedbacks",
          component: () => import("../views/feedbacks/FankView.vue"),
        },

      ],
    },
  ],
})

export default router

下面是前端api接口


import request from '@/utils/request'

// 提交反馈,包括文件上传
export function fetchFeedbackList(formData) {
    return request({
        url: '/feedbacks',
        method: 'post',
        data: formData,
        headers: {
            'Content-Type': 'multipart/form-data' // 重要:设置正确的 Content-Type
        }
    })
}

下面是后端app.js文件


const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const cors = require('cors');
require('dotenv').config();

const adminAuth = require('./middlewares/admin-auth');
const userAuth = require('./middlewares/user-auth');

// 前台路由文件
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const authRouter = require('./routes/auth');
const dzjsRouter = require('./routes/dzjs');
const historiesRouter = require('./routes/histories');
const aliRouter = require('./routes/ali');
const allsRouter = require('./routes/alls');
const dzj111Router = require('./routes/dzj111');
const dzj109Router = require('./routes/dzj109');
const dzj1345Router = require('./routes/dzj1345');
const cidiansRouter = require('./routes/cidians');
const feedbacksRouter = require('./routes/feedbacks' );

// 后台路由文件
const adminDzjsRouter = require('./routes/admin/dzjs');
const adminUsersRouter = require('./routes/admin/users');
const adminAuthRouter = require('./routes/admin/auth');
const adminHistoriesRouter = require('./routes/admin/histories');
const adminLogonsRouter = require('./routes/admin/logons');
const adminAllsRouter = require('./routes/admin/alls');
const adminFeedbacksRouter = require('./routes/admin/feedbacks');

const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// 设置静态文件服务,提供uploads文件夹中的文件
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));


// CORS 跨域配置
app.use(cors());

// 前台路由配置
app.use('/', indexRouter);
app.use('/users', userAuth, usersRouter);
app.use('/dzjs', userAuth, dzjsRouter);
app.use('/dzj111', userAuth, dzj111Router);
app.use('/dzj109', userAuth, dzj109Router);
app.use('/dzj1345', userAuth, dzj1345Router);
app.use('/histories', userAuth, historiesRouter);
app.use('/auth', authRouter);
app.use('/ali',  aliRouter);
app.use('/alls',  allsRouter);
app.use('/cidians',userAuth,  cidiansRouter);
app.use('/feedbacks',userAuth,  feedbacksRouter);

// 后台路由配置
app.use('/admin/dzjs', adminAuth, adminDzjsRouter);
app.use('/admin/users', adminAuth, adminUsersRouter);
app.use('/admin/histories', adminAuth, adminHistoriesRouter);
app.use('/admin/auth', adminAuthRouter);
app.use('/admin/logon', adminLogonsRouter);
app.use('/admin/alls', adminAllsRouter);
app.use('/admin/feedbacks', adminFeedbacksRouter);

module.exports = app;
  • 写回答

2条回答 默认 最新

  • 香格里辣 2024-11-03 11:49
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    看起来你的问题是关于在Vue前端上传文件到后端接口时遇到的错误。根据你提供的错误信息,你在尝试上传文件时收到了一个HTTP 404错误,这通常意味着你正在尝试访问一个不存在的路由或路径。以下是可能导致这个问题的几个原因及其解决方法:

    问题一:URL配置错误

    检查前端路由和后端API端点是否配置正确。特别是,请检查你在前端请求中所使用的URL(/feedbacks)是否与后端API的路由相匹配。确保后端服务器正确设置了处理POST请求的路由。

    问题二:后端服务器未正确配置

    确保你的后端服务器正确配置了处理文件上传的路由。根据你提供的后端代码,看起来/feedbacks路由是配置好的,但是请确保它与你的后端控制器或处理程序匹配,并且能够处理文件上传。

    问题三:跨域问题(CORS)

    有时候,浏览器会因为跨域问题阻止请求。虽然你在后端已经使用了CORS中间件,但请确保它配置正确,允许来自前端的域名进行请求。你可能需要检查CORS的配置,确保它允许你的前端应用程序发送请求。

    问题四:请求头问题

    检查你的请求头是否设置正确。特别是当你发送一个包含文件的FormData对象时,你需要确保请求头中设置了正确的Content-Type。在你的代码中,你已经设置了Content-Typemultipart/form-data,这是正确的。但是,还需要确保后端服务器能够正确解析这个类型的请求。

    问题五:文件上传逻辑问题

    在你的Vue代码中,文件上传的逻辑是在submitFeedbackForm方法中处理的。请确保在这个方法中正确地添加了文件到FormData对象,并且确保文件的格式和大小满足后端服务器的要求。

    总结解决步骤:

    1. 检查前端和后端的路由配置,确保它们匹配并且正确配置。
    2. 检查CORS配置,确保允许来自前端的请求。
    3. 检查请求头是否设置正确。
    4. 检查文件上传的逻辑,确保文件被正确添加到FormData对象并发送到服务器。
    5. 查看后端服务器的日志,查找可能的错误信息或警告,这可能会提供更多关于问题的线索。

    如果以上步骤仍然无法解决问题,你可能需要进一步调试你的代码或寻求更具体的错误信息来解决这个问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月24日
  • 已采纳回答 11月16日
  • 创建了问题 11月3日