首页 > 解决方案 > Angular 使用 GridFS 将文件上传到 mongoDB 用户集合

问题描述

我目前正在开发一个 MEAN stack web 应用程序,它应该允许用户将他们的文件上传到数据库。我一直在尝试使用 multer + gridfs-stream 以及 multer-gridfs-storage 但无济于事。这是我目前拥有的。

// user.component.html

<form [formGroup]="fileUpload">
  <input type="file" id="myFile" formControlName="file">
  <button (click)="upload()">upload</button>
</form>

// user.component.ts

ngOnInit(){  

this.fileUpload = this.formBuilder.group({
      file: ['', Validators.required]
    });
}

upload() {
    this.usersService.upload(this.fileUpload.value.file).subscribe(result => {
      console.log(result);
    })
  }

// user.service.ts(这是将我的客户端连接到服务器端的代码)

  upload(file) {
    return this.http.post('./api/upload', file)
  }

// api.js

const express = require('express');
const router = express.Router();
const MongoClient = require('mongodb').MongoClient;
const crypto = require('crypto');

const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');
const path = require('path');
const multer = require('multer');
const url = "my_mongo_uri";

var db;

//init gfs
let gfs;

MongoClient.connect(url: url,
{ useNewUrlParser: true }, { useUnifiedTopology: true }, (err, database) => {
    if (err) return console.log(err)
    db = database.db('insurance_app');
    gfs = Grid(db, MongoClient);
    gfs.collection('uploads');
});



// Create a storage object with a given config
const storage = new GridFsStorage({url, 
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: 'uploads'
            };
            resolve(fileInfo);
        });
    });
}});

const upload = multer({ storage });



// the endpoint that I am calling
router.post('/upload', upload.single('file'), (req, res) => {
    res.json({file: req.file})
    console.log({file: req.file})
})

但是每当我运行我的代码时,终端中的 console.log 都会返回 me {file: undefined}。我提供了代码,因为我认为这是我最接近工作解决方案的地方。

标签: angulargridfsgridfs-streammulter-gridfs-storage

解决方案


您的upload服务功能应该是

upload(file) {
  const data = new FormData();
  data.append('file', file);
  return this.http.post('./api/upload', data);
}

当您编写upload.single('file')它时,这意味着服务器希望接收一个名为字段的请求,'file'并且该字段的值是一个实际文件。

这正是当您编写data.append('file', file);第一个参数是字段名称而第二个参数是您将发送的值(在本例中为文件)时发生的情况。

Angular 知道FormData值必须被编码为multipart/form-data唯一multer知道如何处理的格式,如库描述中所述:

用于处理的 Node.js 中间件multipart/form-data


推荐阅读