我有一个 mern 应用程序,允许用户在帖子中上传多张图片。图像被上传到 tmp 文件夹,然后上传到 cloudinary,然后从临时文件夹中删除。
本地运行完美,但是当我从服务器尝试时,我收到 400 错误请求错误。当我查看错误时,它显示“未选择文件”。
服务器是在 Ubuntu 上运行的 ngnix。我可以登录并获取帖子,甚至可以从 liver 服务器创建帖子。唯一不起作用的是图像上传。我想知道这是否是文件夹权限问题,但服务器上有一个包含一些图像的 tmp 文件夹,所以我不确定是什么问题。
这是处理图像的 postSubmit 部分:
if (images && images.length) {
const postImages = images.map((img) => {
return dataURItoBlob(img);
});
const path = `tyt/${user.user.username}/test_images`;
let formData = new FormData();
formData.append('path', path);
postImages.forEach((image) => {
formData.append('file', image);
});
const response = await uploadImages(formData, path, user.token);
console.log('response :', response);
const res = await createPost(
null,
text,
response,
user.user._id,
user.token
);
setLoading(false);
if (res) {
setPostVisible(false);
setText('');
setImages('');
dispatch({ type: 'ADDPOST_SUCCESS', data: res });
}
}
本页面调用uploadImages函数:
import axios from 'axios';
export const uploadImages = async (formData, path, token) => {
try {
const { data } = await axios.post('/api/uploadImages', formData, {
headers: {
Authorization: `Bearer ${token}`,
'content-type': 'multipart/form-data',
},
});
return data;
} catch (error) {
return error;
}
};
这是 server.js:
const express = require('express');
const cors = require('cors');
const fileUpload = require('express-fileupload');
const AuthRoute = require('./routes/AuthRoute.js');
const connectDB = require('./config/db.js');
const colors = require('colors');
const dotenv = require('dotenv');
dotenv.config();
const PostRoute = require('./routes/PostRoute.js');
const UploadRoute = require('./routes/UploadRoute.js');
const PORT = 8000;
const app = express();
app.use(express.json());
app.use(cors());
app.use(
fileUpload({
useTempFiles: true,
})
);
app.use('/api/auth', AuthRoute);
app.use('/api/posts', PostRoute);
app.use('/api/', UploadRoute);
connectDB();
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`.yellow.bold);
});
这里是 uploadImages 路线:
const express = require('express');
const { uploadImages } = require('../controllers/upload');
const { authUser } = require('../middleware/auth');
const imageUpload = require('../middleware/imageUpload');
const router = express.Router();
router.post('/uploadImages', imageUpload, uploadImages);
module.exports = router;
这是图像上传功能:
const fs = require('fs');
module.exports = async function (req, res, next) {
try {
if (!req.files || Object.values(req.files).flat().length === 0) {
return res.status(400).json({ message: 'No files selected' });
}
let files = Object.values(req.files).flat();
files.forEach((file) => {
if (
file.mimetype !== 'image/jpeg' &&
file.mimetype !== 'image/jpg' &&
file.mimetype !== 'image/png' &&
file.mimetype !== 'image/gif' &&
file.mimetype !== 'image/webp'
) {
removeTemp(file.tempFilePath);
return res.status(400).json({ message: 'Unsupported format' });
}
console.log('check file size');
if (file.size > 1024 * 1024 * 40) {
removeTemp(file.tempFilePath);
return res.status(400).json({ message: 'File size is too large' });
}
});
console.log('next');
next();
} catch (error) {
return res.status(500).json({ message: error.message });
}
};
const removeTemp = (path) => {
fs.unlink(path, (err) => {
if (err) throw new err();
});
};
这里是带有 cloudinary 函数的上传控制器:
const cloudinary = require('cloudinary');
const fs = require('fs');
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_API_KEY,
api_secret: process.env.CLOUD_API_SECRET,
});
exports.uploadImages = async (req, res) => {
try {
const { path } = req.body;
let files = Object.values(req.files).flat();
let images = [];
for (const file of files) {
const url = await uploadToCloudinary(file, path);
images.push(url);
}
res.json(images);
} catch (error) {
return res.status(500).json({ message: error.message });
}
};
const uploadToCloudinary = async (file, path) => {
return new Promise((resolve) => {
cloudinary.v2.uploader.upload(
file.tempFilePath,
{
folder: path,
},
(err, res) => {
if (err) {
removeTemp(file.tempFilePath);
return res.status(400).json({ message: 'Image upload failed' });
}
resolve({
url: res.secure_url,
});
}
);
});
};
const removeTemp = (path) => {
fs.unlink(path, (err) => {
if (err) throw new err();
});
};