【发布时间】:2020-09-15 19:51:18
【问题描述】:
我想用 multer 使用 nodejs/angular 应用程序添加文件。相同的代码(nodejs 部分)在 nodejs/react-redux 应用程序上运行良好。
这是 server.js 代码(其中最重要的是消息路由):
const express = require('express');
const cors = require('cors');
const path = require('path');
const mongoose = require('mongoose');
require('dotenv').config();
require('./modules/auth');
const passport = require('passport');
const cookieSession = require('cookie-session');
const bodyParser = require('body-parser');
// #6 Initialize an Express application
const app = express();
// Bodyparser MiddlewareFirst way
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb', extended: false}));
// Bodyparser Middleware - second way
app.use(express.json());
app.use(cors());
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
app.use(passport.initialize());
app.use(passport.session());
const db = process.env.mongoURI;
// Connect to Mongo
mongoose
.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false }) // Adding new mongo url parser
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
app.use('/api/messages', require('./routes/api/messages'));
app.use('/api/posts', require('./routes/api/posts'));
app.use('/auth', require('./routes/auth'));
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'))
});
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
我还尝试删除/注释所有内容,例如模块/身份验证、所有护照部分代码和其他路由,但它仍然不起作用。(当 console.log 连接时,我看到只有用户模型/架构/集合包括,即使我有三个模型(和三个路由)。所以我也尝试使用身份验证路由添加文件,但它也不起作用。
所以现在我将显示我的消息路由(当我不添加任何文件时,它可以正常工作,因此必须打开连接)。
routes/api/messages.js
const router = require('express').Router();
const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const { initStorage, initUpload } = require('../../modules/multerModule');
const conn = mongoose.connection;
Grid.mongo = mongoose.mongo;
// console.log(conn);
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db);
gfs.collection(collectionName);
});
const collectionName = 'messages';
const bucketName = 'messages';
console.log(conn);
const storage = initStorage(conn, bucketName);
const upload = initUpload(storage);
// File Model
const Message = require('../../models/message');
// @route GET /
// @desc Loads form
router.get('/', (req, res) => {
Message.find()
.sort({ date: 1 })
.then(messages => res.json(messages))
});
// @route POST /upload
// @desc Uploads file and object to DB
router.post('/', upload.single('message'), (req, res) => {
const fileImage = (req.body.fileImage == 'true');
console.log(fileImage);
if (req.files !== undefined) {
const { files } = req;
const { id, filename } = files[0];
const newMessage = new Message({
files_id: id,
fileImage: req.body.fileImage,
path: '/api/messages/image/' + filename,
content: req.body.content
// Grab the file id that was stored in the database by the storage engine as the messages to your file
})
newMessage.save().then(messages => res.json(messages));
}
else {
const newMessage = new Message({
files_id: mongoose.Types.ObjectId(),
path: req.body.path,
fileImage: req.body.fileImage,
content: req.body.content
// Grab the file id that was stored in the database by the storage engine as the messages to your file
})
newMessage.save().then(messages => res.json(messages));
}
});
// ... here's also put and gets filename routes, but that's not important right now
module.exports = router;
还有我的存储功能:
模块/multerModule.js
const path = require('path');
const multer = require('multer');
const crypto = require('crypto');
const GridFsStorage = require('multer-gridfs-storage');
// Create storage engine
const initStorage = (conn, bucketName) => 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: bucketName
};
resolve(fileInfo);
});
});
}
});
// Create upload module
const initUpload = (storage) => multer({
storage: storage,
fileFilter: function (req, file, callback) {
const ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
}
});
module.exports = { initStorage, initUpload };
我已经尝试了所有方法,如果您知道为什么它不起作用,请与我分享。
这是我的连接数据的一些截图:
我对代码进行了一次更改并得到了新的错误,但它正在向前发展:
我在使用之前已经导入了路线:
const messages = require('./routes/api/messages');
const posts = require('./routes/api/posts');
const auth = require('./routes/auth');
//...
app.use('/api/messages', messages);
app.use('/api/posts', posts);
app.use('/auth', auth);
我得到这个错误:
TypeError: Cannot read property 'isConnected' of undefined
导致initStorage函数:
const conn = mongoose.connection;
Grid.mongo = mongoose.mongo;
// console.log(conn);
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db);
gfs.collection(collectionName);
});
const collectionName = 'messages';
const bucketName = 'messages';
console.log(conn);
const storage = initStorage(conn, bucketName); // here comes the error, but it can be connected with conn variable.
还有initStorage函数(我会再展示一遍):
const path = require('path');
const multer = require('multer');
const crypto = require('crypto');
const GridFsStorage = require('multer-gridfs-storage');
// Create storage engine
const initStorage = (conn, bucketName) => 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: bucketName
};
resolve(fileInfo);
});
});
}
});
【问题讨论】:
标签: javascript node.js mongoose multer gridfs