图像不会使用base64上传到Mongodb。存储为空数组

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

我是开发新手,如果我的代码看起来不完美,请不要无礼,我真的正在尽最大努力。

我正在使用 meern 堆栈、axios 等创建一个 c2c 电子商务平台。在此我尝试制作一个组件,用户可以将带有标题、价格和描述的图像上传到 mongoDB 数据库进行存储和然后可以在用户查看“最新列表”页面时重新调用并显示。 我已成功附加我的 mongoDB 数据库,因为列表详细信息的其余部分已发送到数据库,只有图像作为空数组发送 - 在检查 MongoDB 时,我看到“images: Array”。

我(尝试)使用base64将图像转换为字符串进行存储,但我显然在某个地方出错了-解决人们问题的其他解决方案都不像我的那样小众,因此我不能找到我的。

感谢您的帮助,我很感激!

CreateListing.jsx(列表上传表单):

export default class CreateListing extends Component {
  constructor(props) {
    super(props);

    this.state = {
      title: '',
      price: '',
      description: '',
      images: [],
      currentImageIndex: 0,
    };
  }
......
......
onImageUpload = (e) => {
    const imageFile = e.target.files[0];

    const reader = new FileReader();
    reader.onload = (event) => {
      const base64Image = event.target.result;
      this.setState((prevState) => ({
      images: [...prevState.images, base64Image],
     }));
  };
  if (imageFile) {
    reader.readAsDataURL(imageFile);
  }
};
......
......
onSubmit = (e) => {
    e.preventDefault();
  
    const formData = new FormData();
  
    
    formData.append('title', this.state.title);
    formData.append('price', this.state.price);
    formData.append('description', this.state.description);

  
    
    for (let i = 0; i < this.state.images.length; i++) {
      formData.append('images[]', this.state.images[i]);
    }
  
    axios.post('http://localhost:8000/listings/add', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
    }})
    .then(response => {
      console.log('Listing created!', response.data);
      window.location = '/';
    })
    .catch(error => {
      console.error('Error creating Listing :(', error);
    });
  };

ListingRoute.js:

router.post('/listings/add', (req, res) => {
  const { title, price, description, images } = req.body;

  const newListing = new Listing({
    title,
    price,
    description,
    images,
  });

  newListing
  .save()
  .then(() => {
    res.json('Listing added!')
  })
  .catch((err) => {
    res.status(400).json('Error: ' + err);
  })
});


router.route('/').get((req, res) => {
    Listing.find()
    .then (listings => res.json(listings))
    .catch(err => res.status(400)('Error: ' + err));
});


router.route('/add').post((req, res) => {
    const title = req.body.title;
    const price = req.body.price;
    const description = req.body.description;
    const images = req.body.images;

    const newListing = new Listing({
        title,
        price,
        description,
        images: [],
    });

    newListing.save()
    .then(() => res.json('Listing added!'))
    .catch(err => res.status(400).json('Error: ' + err));
});

列表(架构):

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const listingSchema = new Schema({
    title: {
        type: String,
        trim: true,
        minlength: 6
    },
    price: {
        type: Number,
        trim: true,
    },
    description: {
        type: String,
        minlength: 10
    },
    images: [String],
});

const Listing = mongoose.model('Listing', listingSchema);

module.exports = Listing;

我最初使用的是 multer,但通过一些研究发现人们正在用它代替 Base64,因此朝着这个方向发展。

reactjs mongodb axios base64 mern
1个回答
0
投票

将图像数据编码为 base64 字符串只会增加不必要的开销。

我会将图像存储为 Buffer 类型...

images: [Buffer],

在前端,您只需将

File
对象存储在状态中

onImageUpload = (e) => {
  const imageFile = e.target.files[0];

  if (imageFile) {
    this.setState((prevState) => ({
      images: [...prevState.images, imageFile],
    }));
  }
};

并将它们附加到您的

FormData

this.state.images.forEach((image) => {
  formData.append("images", image); // you don't need the "[]" suffix
});

// Don't set the content-type header, your browser will set it automatically
axios.post('http://localhost:8000/listings/add', formData)
  .then(({ data }) => {
    // ...
  })

在 Express 中,使用 Multer 来处理上传和检索缓冲区

// use in-memory storage if you're just keeping files in MongoDB
const storage = multer.memoryStorage(); 
const upload = multer({ storage });

router.post('/listings/add', upload.array("images"), (req, res) => {
  const { title, price, description } = req.body;
  const images = req.files.map(({ buffer }) => buffer);

  const newListing = new Listing({
    title,
    price,
    description,
    images,
  });
© www.soinside.com 2019 - 2024. All rights reserved.