图片上传到 cloudinary 在本地有效,但在服务器上无效

问题描述 投票:0回答:0

我有一个 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();
  });
};
reactjs mern cloudinary
© www.soinside.com 2019 - 2024. All rights reserved.