使用multer将文件上传到mongodb数据库

我无法将文件上传到数据库。对我来说,保持文件结构很重要。  这是我的文件结构: 服务器:Server structure 在这种情况下最重要的苍蝇:

server.js:

const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const methodOverride = require('method-override');
const config = require('config');
const app = express();


// Bodyparser Middleware
app.use(express.json());
app.use(methodOverride('_method'));

// DB Config
const db = config.get('mongoURI');


// // Connect to Mongo
mongoose
  .connect(db,{
    useNewUrlParser: true,useCreateIndex: true,useUnifiedTopology: true
  }) // Adding new mongo url parser
  .then(() => console.log('MongoDB Connected...'))
  .catch(err => console.log(err));


// Use Routes
app.use('/api/items',require('./routes/api/items'));
app.use('/api/users',require('./routes/api/users'));
app.use('/api/auth',require('./routes/api/auth'));
app.use('/api/files',require('./routes/api/files'));


// Serve static assets if in production
if (process.env.NODE_ENV === 'production') {
  // Set static folder
  app.use(express.static('client/build'));

  app.get('*',(req,res) => {
    res.sendFile(path.resolve(__dirname,'client','build','index.html'));
  });
}

const port = process.env.PORT || 5000;

app.listen(port,() => console.log(`Server started on port ${port}`));

models / File.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create Schema
const FileSchema = new Schema({
  path: {
    type: String,required: true
  }
});

module.exports = File = mongoose.model('file',FileSchema);

routes / api / files.js(这里的post方法是最大的问题)

const router = require('express').Router();
const multer = require('multer');
const crypto = require('crypto');
const GridFsStorage = require('multer-gridfs-storage');
const auth = require('../../middleware/auth');

const mongoose = require('mongoose');
const Grid = require('gridfs-stream');

const conn = mongoose.connection;
Grid.mongo = mongoose.mongo;
// Init gfs
let gfs;


conn.once('open',() => {
  // Init stream
  gfs = Grid(conn.db);
  gfs.collection('files');
});

// // Create storage engine
const storage = new GridFsStorage({
  db: conn,file: (req,file) => {
    return new Promise((resolve,reject) => {
      crypto.randomBytes(16,(err,buf) => {
        if (err) {
          return reject(err);
        }
        const filename = buf.toString('hex') + path.extname(file.originalname);
        const fileInfo = {
          filename: filename,bucketName: 'files'
        };
        resolve(fileInfo);
      });
    });
  }
});
const upload = multer({ storage });

// File Model
const File = require('../../models/File');

// @route GET /
// @desc Loads form
router.get('/',res) => {
  gfs.files.find().toArray((err,files) => {
    // Check if files
    if (!files || files.length === 0) {
      // res.render('index',{ files: false });
    } else {
      files.map(file => {
        if (
          file.contentType === 'image/jpeg' ||
          file.contentType === 'image/png'
        ) {
          file.isImage = true;
        } else {
          file.isImage = false;
        }
      });
      // res.render('index',{ files: files });
    }
  });
});

// @route POST /upload
// @desc  Uploads file to DB
router.post('/',upload.single('file'),res) => {
  const newFile = new File({
    path: req.body.name
  });
  newFile.save();
  // newFile.save().then(file => res.json({ file: req.file }));
});

// @route GET /files
// @desc  Display all files in JSON
router.get('/',files) => {
    // Check if files
    if (!files || files.length === 0) {
      return res.status(404).json({
        err: 'No files exist'
      });
    }

    // Files exist
    return res.json(files);
  });
});

// @route GET /files/:filename
// @desc  Display single file object
router.get('/:filename',res) => {
  gfs.files.findOne({ filename: req.params.filename },file) => {
    // Check if file
    if (!file || file.length === 0) {
      return res.status(404).json({
        err: 'No file exists'
      });
    }
    // File exists
    return res.json(file);
  });
});

// @route GET /image/:filename
// @desc Display Image
router.get('image/:filename',file) => {
    // Check if file
    if (!file || file.length === 0) {
      return res.status(404).json({
        err: 'No file exists'
      });
    }

    // Check if image
    if (file.contentType === 'image/jpeg' || file.contentType === 'image/png') {
      // Read output to browser
      const readstream = gfs.createReadStream(file.filename);
      readstream.pipe(res);
    } else {
      res.status(404).json({
        err: 'Not an image'
      });
    }
  });
});

// @route DELETE /files/:id
// @desc  Delete file
router.delete('/:id',res) => {
  gfs.remove({ _id: req.params.id,root: 'files' },gridStore) => {
    if (err) {
      return res.status(404).json({ err: err });
    }

    res.redirect('/');
  });
});

module.exports = router;

客户:Client structure

为了不使其过于复杂,我将添加组件(与reactsrap一起使用):

SliderModal.js

import React,{ Component } from 'react';
import {
  Button,Modal,ModalHeader,ModalBody,Form,FormGroup,Label,Input
} from 'reactstrap';
import { connect } from 'react-redux';
import { addFile } from '../actions/fileactions';
import PropTypes from 'prop-types';

class SliderModal extends Component {
  state = {
    modal: false,name: ''
  };

  static propTypes = {
    isAuthenticated: PropTypes.bool
  }

  toggle = () => {
    this.setState({
      modal: !this.state.modal
    });
  };

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

  onSubmit = e => {
    e.preventDefault();

    const newFile = {
      name: this.state.name
    }

    // Add item via addFile action
    this.props.addFile(newFile);

    // Close modal
    this.toggle();
  }
  render() {
    return (
      <div>
        {this.props.isAuthenticated ?
          <Button
            color="dark"
            style={{ marginBottom: '2rem' }}
            onClick={this.toggle}
          >Add File
          </Button> :
          <h4 classname="mb-3 ml-4">Please login to manage files</h4>
        }

        <Modal
          isOpen={this.state.modal}
          toggle={this.toggle}
        >
          <ModalHeader toggle={this.toggle}>Add To Files List</ModalHeader>
          <ModalBody>
            <Form onSubmit={this.onSubmit}>
              <FormGroup>
                <Label for="file">File</Label>
                <Input
                  type="file"
                  name="name"
                  id="file"
                  placeholder="Add file"
                  onChange={this.onChange}
                />
                <Button
                  color="dark"
                  style={{ marginTop: '2rem' }}
                  block>
                  Add File
                </Button>
              </FormGroup>
            </Form>
          </ModalBody>
        </Modal>
      </div>
    );
  }
}

const mapstatetoProps = state => ({
  file: state.file,isAuthenticated: state.auth.isAuthenticated
});

export default connect(mapstatetoProps,{ addFile })(SliderModal);

这是我的代码的结果: Result from atlas cluster

我只有此路径和ID名称,但是我希望所有文件都上传到数据库中并显示在我的页面上。该用户和项目集合可以很好地工作。 我认为最重要的是:  路由/api/files.js和模型/File.js文件。

hlw13781927235 回答:使用multer将文件上传到mongodb数据库

现在,我在加载文件时遇到了一些问题。 本地主机:5000 / api /文件甚至无法加载,而且我经常遇到与api /文件有关的代理错误。

Proxy error: Could not proxy request /api/files from localhost:3000 to http://localhost:5000.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).

files.js

const router = require('express').Router();
const multer = require('multer');
const crypto = require('crypto');
const GridFsStorage = require('multer-gridfs-storage');
const auth = require('../../middleware/auth');

const mongoose = require('mongoose');
const Grid = require('gridfs-stream');

const conn = mongoose.connection;
Grid.mongo = mongoose.mongo;
// Init gfs
let gfs;


conn.once('open',() => {
  // Init stream
  gfs = Grid(conn.db);
  gfs.collection('files');
});

// // Create storage engine
const storage = new GridFsStorage({
  db: conn,file: (req,file) => {
    return new Promise((resolve,reject) => {
      crypto.randomBytes(16,(err,buf) => {
        if (err) {
          return reject(err);
        }
        const filename = buf.toString('hex') + path.extname(file.originalname);
        const fileInfo = {
          filename: filename,bucketName: 'files'
        };
        resolve(fileInfo);
      });
    });
  }
});
const upload = multer({ storage });

// File Model - don't need right now
// const File = require('../../models/File');

// @route GET /
// @desc Loads form
router.get('/',(req,res) => {
  gfs.files.find().toArray((err,files) => {
    // Check if files
    if (!files || files.length === 0) {
      // res.render('index',{ files: false });
    } else {
      files.map(file => {
        if (
          file.contentType === 'image/jpeg' ||
          file.contentType === 'image/png'
        ) {
          file.isImage = true;
        } else {
          file.isImage = false;
        }
      });
      // res.render('index',{ files: files });
    }
  });
});

在route.get上,我遇到了gfs.file行的问题:

TypeError: Cannot read property 'files' of undefined
[0]     at router.get (/home/fakepath/ProjectFolder/routes/api/files.js:49:7)
[0]     at Layer.handle [as handle_request] (/home/fakepath/ProjectFolder/node_modules/express/lib/router/layer.js:95:5)
[0]     at next (/home/fakepath/ProjectFolder/node_modules/express/lib/router/route.js:137:13)
[0]     at Route.dispatch (/home/fakepath/ProjectFolder/node_modules/express/lib/router/route.js:112:3)
[0]     at Layer.handle [as handle_request] (/home/fakepath/ProjectFolder/node_modules/express/lib/router/layer.js:95:5)
[0]     at /home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:281:22
[0]     at Function.process_params (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:335:12)
[0]     at next (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:275:10)
[0]     at Function.handle (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:174:3)
[0]     at router (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:47:12)
[0]     at Layer.handle [as handle_request] (/home/fakepath/ProjectFolder/node_modules/express/lib/router/layer.js:95:5)
[0]     at trim_prefix (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:317:13)
[0]     at /home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:284:7
[0]     at Function.process_params (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:335:12)
[0]     at next (/home/fakepath/ProjectFolder/node_modules/express/lib/router/index.js:275:10)
[0]     at /home/fakepath/ProjectFolder/server.js:33:3

所以我无法访问api /文件,显示图像,从数据库中获取图像(已上传到那里)并且不了解gfs.files.find的问题。

本文链接:https://www.f2er.com/3116948.html

大家都在问