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



下面是前端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;