使用 Cloudinary 和 MongoDB 时 URL 中出现“未定义”问题

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

我目前正在开发一个项目,后端使用 Express.js,前端使用 React。该项目涉及将图像上传到 Cloudinary,然后将 Cloudinary URL 保存在 MongoDB 数据库中。但是,我遇到了一个问题,即存储在数据库中的 Cloudinary URL 开头包含“未定义”字符串。

问题描述:

这是我的项目中的步骤顺序:

前端:我选择要上传的图像,并使用 Cloudinary API 正确获取了该图像的 Cloudinary URL。

后端(Express.js):我将 Cloudinary URL 从前端发送到服务器并将其存储在 MongoDB 数据库中。

但是,当我稍后从数据库检索 Cloudinary URL 时,它显示为 “undefined”后跟实际的 Cloudinary URL (例如:“未定义http://res.cloudinary.com/...”)。

后端:

// Back-end code for handling image upload
const express = require('express');
const router = express.Router();
const cloudinary = require('../utils/cloudinary');

//upload

const upload = multer({ dest: 'uploads' });

// ... (other imports and middleware)

// POST /upload/image
// Upload product images
// Protected route (isAuth middleware checks authentication)

router.post('/image', isAuth, upload.single('image'), async (req, res) => {
  try {
    const file = req.file.path;

    // Upload the image to Cloudinary
    const result = await cloudinary.uploader.upload(file);

    // Check if the image was successfully uploaded to Cloudinary
    if (!result || !result.url) {
      return res.status(500).json({ errors: { msg: 'Image upload failed' } });
    }

    // If the image was uploaded successfully, save the Cloudinary URL in the database
    const imagePath = result.url;

    // ... (other code for saving imagePath to MongoDB)

    res.status(200).json({ imagePath });
  } catch (error) {
    console.error(error);
    res.status(500).json({ errors: { msg: 'Server error' } });
  }
});

// ... (other routes)

前端

const [form, setForm] = useState({
    productName: '',
    description: '',
    basePrice: 0,
    duration: 300,
    category: '',
    image: '',
  });
  const [file, setFile] = useState('');
  const [fileName, setFileName] = useState('Choose your image file...');
  const [fileValid, setFileValid] = useState(true);
  const [uploading, setUploading] = useState(false);
  let navigate = useNavigate();

  useEffect(() => {
    return () => {
      props.clearAlerts();
    };
  }, []);

  const handleFormChange = (e) => {
    e.preventDefault();
    setForm({
      ...form,
      [e.target.name]: e.target.value,
    });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    // Check for empty fields
    if (form.productName === '') {
      return props.setAlert('Product name required!');
    }
    if (form.basePrice.toString() === '0') {
      return props.setAlert('Base price required!');
    }
    if (form.duration.toString() === '0') {
      setForm({ ...form, duration: 300 });
    }
    if (!fileValid) {
      // if selected file is not image/exceeds size limit
      props.setAlert('Image file not valid!', 'error');
    } else {
      if (file === '') {
        // submit without photo
        await props.postAd(form);
        navigate('/');
      } else {
        // with photo
        const imagePath = await uploadImage();
        console.log(imagePath);
        if (imagePath) {
          await props.postAd({ ...form, image: imagePath });
          navigate('/');
        }
      }
    }
  };

  const fileSelected = (e) => {
    let filesize = (e.target.files[0].size / (1024 * 1024)).toFixed(3);
    let fileType = e.target.files[0].type.toString();
    let regex = /^image\/(png|jpg|jpeg|gif)$/;
    // if (fileType !== 'image/jpeg' && fileType !== 'image/png') {
    if (!regex.test(fileType)) {
      props.setAlert('Image must be of type JPEG, PNG or GIF');
      setFile('');
      setFileValid(false);
    } else if (filesize > 3) {
      props.setAlert('Image size must be less than 3 MB', 'error');
      setFile('');
      setFileValid(false);
    } else {
      setFileValid(true);
      setFile(e.target.files[0]);
      setFileName(e.target.files[0].name);
      console.log(e.target.files[0]);
      
    }
  };




const uploadImage = async () => {
  setUploading(true);
    const formData = new FormData();
    formData.append('image', file);
    console.log(file)
    console.log(formData)
    try {
      const res = await axios.post(
        `${process.env.REACT_APP_API_BASE_URL}/upload/image`,
        formData,
        { headers: { 'Content-Type': 'multipart/form-data' } }
      );
      console.log(res.data)
      return res.data.imagePath;
    } catch (error) {
      console.log(error);
      setUploading(false);
      props.setAlert('File upload failed', 'error');
    }
};



背景:

  • 处理图像上传到Cloudinary并保存URL的代码 MongoDB 似乎按预期运行,但问题 稍后从数据库检索 URL 时会出现。

  • imagePath 变量已正确填充 Cloudinary URL 在将其保存到数据库之前,并且在保存时没有问题 图片上传后发送URL到前端。

javascript node.js mongodb backend cloudinary
1个回答
0
投票

这可能源于您上传图像后在前端处理响应的方式。你能尝试像这样添加验证吗?

  try {
    const res = await axios.post(
      `${process.env.REACT_APP_API_BASE_URL}/upload/image`,
      formData,
      { headers: { 'Content-Type': 'multipart/form-data' } }
    );

    if (res.data && typeof res.data.imagePath === 'string') {
      return res.data.imagePath;
    } else {
      return 'Default URL or handle the error';
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.