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



我无法将文件上传到数据库中。维护我的文件结构对我来说很重要。以下是我的文件结构:服务器:服务器结构这种情况下最重要的苍蝇:

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('/', (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 POST /upload
// @desc  Uploads file to DB
router.post('/', upload.single('file'), (req, 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('/', (req, res) => {
gfs.files.find().toArray((err, 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', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, 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', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, 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', (req, res) => {
gfs.remove({ _id: req.params.id, root: 'files' }, (err, gridStore) => {
if (err) {
return res.status(404).json({ err: err });
}
res.redirect('/');
});
});
module.exports = router;

客户端:客户端结构

为了不让它太复杂,我将添加组件(使用reatsrap(:

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);

以下是我的代码结果:图谱聚类结果

我只有这个路径和ID名称,但我希望所有文件都能上传到数据库中,并显示在我的页面上。该用户和项目集合工作得非常好。我认为最重要的是:routes/api/files.js和models/File.js文件。

现在我在加载文件时遇到了一个小问题。localhost:5000/api/files甚至无法加载,而且我经常遇到与api/files相关的代理错误。

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.文件行的问题:

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.的问题

最新更新