使用 Nodejs、Express、Mongoose 和 React 将图像上传到 MongoDB

Posted

技术标签:

【中文标题】使用 Nodejs、Express、Mongoose 和 React 将图像上传到 MongoDB【英文标题】:Upload an image to MongoDB using Nodejs, Express, Mongoose and React 【发布时间】:2020-06-28 13:02:11 【问题描述】:

我正在开发一个简单的网络应用程序来练习我新开发的网络开发技能。我正在尝试使用 Nodejs、Express、Mongoose 和 React 将一本书的一些信息及其图像上传到 MongoDB。到目前为止,我可以通过单击提交按钮将所有信息上传到 MongoDB。但是每当我尝试将图像添加到猫鼬模式时,发布请求都不起作用。我无法弄清楚我的代码的问题。 这是 Book 模型的代码:

const mongoose = require("mongoose");

const BookSchema = new mongoose.Schema(
  image: 
    data: Buffer,
    contentType: String
  ,
  title: 
    type: String,
    required: true
  ,
  isbn: 
    type: String,
    required: true
  ,
  author: 
    type: String,
    required: true
  ,
  description: 
    type: String
  ,
  published_date: 
    type: Date
  ,
  publisher: 
    type: String
  ,
  updated_date: 
    type: Date,
    default: Date.now
  
);

module.exports = Book = mongoose.model("book", BookSchema);

这里是发布请求的代码:

router.post("/", (req, res) => 
  var title= req.body.title;
  var isbn = req.body.isbn;
  var author = req.body.author;
  var description = req.body.description;
  var published_date= req.body.published_date;
  var publisher = req.body.publisher;
  var updated_date = req.body.updated_date;

  var imgPath = req.file.path;
  var image = Book.image.data = fs.readFileSync(imgPath);
  Book.image.contentType = 'image/jpg';

  var newBook = image: image, title: title, isbn: isbn, author: author, description: description, 
  published_date: published_date, publisher: publisher, updated_date: updated_date;
  Book.create(newBook, function(err, newlyCreated)
    if (err) 
        console.log(err);
     else 
        console.log(newlyCreated);
    
 );

)

这是使用 React 的前端代码:

import React,  Component  from "react";
import  Link  from "react-router-dom";
import "../App.css";
import axios from "axios";

class CreateBook extends Component 
  constructor() 
    super();
    this.state = 
      image: "",
      title: "",
      isbn: "",
      author: "",
      description: "",
      published_date: "",
      publisher: ""
    ;
    this.onFileChange = this.onFileChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  

  onChange = e => 
    this.setState( [e.target.name]: e.target.value );
  ;

  onFileChange = e => 
    this.setState( [e.target.name]: e.target.files[0] )
  

  onSubmit = e => 
    e.preventDefault();
    const formdata = new FormData()

    formdata.append('image', this.state.image)
    formdata.append('title', this.state.title);
    formdata.append('isbn', this.state.isbn,);
    formdata.append('author', this.state.author);
    formdata.append('description', this.state.description);
    formdata.append('published_date', this.state.published_date);
    formdata.append('publisher', this.state.publisher);


    axios
      .post("http://localhost:8082/api/books", formdata)
      .then(res => 
        console.log(res);
        this.setState(
          image: "",
          title: "",
          isbn: "",
          author: "",
          description: "",
          published_date: "",
          publisher: ""
        );
        this.props.history.push("/");
      )
      .catch(err => 
        console.log("Error in CreateBook!");
      );
  ;

  render() 
    return (
      <div className="CreateBook">
        <div className="container">
          <div className="row">
            <div className="col-md-8 m-auto">
              <br />
              <Link to="/" className="btn btn-outline-warning float-left">
                Show BooK List
              </Link>
            </div>
            <div className="col-md-8 m-auto">
              <h1 className="display-4 text-center">Add Book</h1>
              <p className="lead text-center">Create new book</p>

              <form noValidate onSubmit=this.onSubmit>
                <div className="form-group">
                  <input
                    type="file"
                    placeholder="Browse Image"
                    name="image"
                    className="form-control"

                    onChange=this.onFileChange
                  />
                </div>
                <button type="button" className="btn btn-primary mb-3">
                  Upload
                </button>
                <br />
                <div className="form-group">
                  <input
                    type="text"
                    placeholder="Title of the Book"
                    name="title"
                    className="form-control"
                    value=this.state.title
                    onChange=this.onChange
                  />
                </div>
                <br />

                <div className="form-group">
                  <input
                    type="text"
                    placeholder="ISBN"
                    name="isbn"
                    className="form-control"
                    value=this.state.isbn
                    onChange=this.onChange
                  />
                </div>

                <div className="form-group">
                  <input
                    type="text"
                    placeholder="Author"
                    name="author"
                    className="form-control"
                    value=this.state.author
                    onChange=this.onChange
                  />
                </div>

                <div className="form-group">
                  <input
                    type="text"
                    placeholder="Describe this book"
                    name="description"
                    className="form-control"
                    value=this.state.description
                    onChange=this.onChange
                  />
                </div>

                <div className="form-group">
                  <input
                    type="date"
                    placeholder="published_date"
                    name="published_date"
                    className="form-control"
                    value=this.state.published_date
                    onChange=this.onChange
                  />
                </div>
                <div className="form-group">
                  <input
                    type="text"
                    placeholder="Publisher of this Book"
                    name="publisher"
                    className="form-control"
                    value=this.state.publisher
                    onChange=this.onChange
                  />
                </div>

                <input
                  type="submit"
                  className="btn btn-outline-warning btn-block mt-4"
                />
              </form>
            </div>
          </div>
        </div>
      </div>
    );
  


export default CreateBook;

我会非常感谢任何建议。提前致谢。

【问题讨论】:

你得到什么错误? 点击提交按钮后,控制台报错:加载资源失败:服务器响应状态为500(内部服务器错误)。如果我从 Book 模式中排除图像,整个代码工作正常。 在 NodeJS 后端,尝试使用 multer 包。可能对你有用 【参考方案1】:

如果您使用“jpeg / png”格式的图像并且它们小于 16mb,则可以使用这个 github repo,它是一个有助于将图像轻松保存到 mongodb 的模块,并且没有 GRIDFS 的复杂性,但是如果您的文件大于 16mb,则需要使用 GRIDFS,

这是小于 16 mb 图像的 github 存储库链接(也适用于 react)

https://github.com/saran-surya/Mongo-Image-Converter

希望这会有所帮助:)

【讨论】:

以上是关于使用 Nodejs、Express、Mongoose 和 React 将图像上传到 MongoDB的主要内容,如果未能解决你的问题,请参考以下文章

求助:关于nodejs使用express,报错:模块缺失

nodejs中的express啥意思

nodejs安装使用express

Nodejs / Express - 启动我的应用程序:不推荐使用 express.createServer()

nodejs+express+ejs生成项目

Nodejs搭建基于express的应用,使用脚手架工具--express-generator