【问题标题】:Angular upload files to mongoDB user collection using GridFSAngular 使用 GridFS 将文件上传到 mongoDB 用户集合
【发布时间】:2020-12-07 16:53:25
【问题描述】:

我目前正在开发一个 MEAN 堆栈网络应用程序,它应该允许用户将他们的文件上传到数据库。我一直在尝试使用 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 都会返回给我{file: undefined}。我提供了我认为最接近有效解决方案的代码。

【问题讨论】:

    标签: angular gridfs gridfs-stream multer-gridfs-storage


    【解决方案1】:

    {file: undefined} 正在打印到控制台,因为您打印的是 console.log({file: req.file} 而不是 console.log({file: req.body.file})。这将为您提供您正在寻找的文件名。

    【讨论】:

      【解决方案2】:

      你的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 知道如何处理的唯一格式,如库描述中所述:

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

      【讨论】:

      • 嘿@devconcept,感谢您的回复。虽然在更改了我的 service.ts 之后,我的结果仍然给了我一个{file: undefined}。有什么想法吗?也许我写错了api.js,尤其是我初始化gfs的部分,因为我在实施过程中不确定。另外,我一直在阅读您关于 multer-gridfs-storage 的文档,我只能说它简洁易读!
      • 此外,我已经更新了上面的问题,以提供有关我的 api.js 文件的更多数据。
      • 如果您写const storage = new GridFsStorage({url,...,将自动创建一个新连接。这意味着您在gsf 部分中写入的任何内容都与文件存储无关。您的代码应该可以更新角度服务。你为什么使用this.http.post('./api/upload'...?应该是this.http.post('http://myapiendpoint/api/upload' 还是类似的东西?
      • 很遗憾,上传到数据库仍然无法正常工作。另外,我正在使用this.http.post('./api/upload'...,因为我已经预先定义了api 以直接路由到我的服务器。
      • @BrioTech 在您的user.component upload 方法中,this.fileUpload.value.file 的类型是File?使用控制台并检查结果值
      猜你喜欢
      • 2012-03-22
      • 1970-01-01
      • 2020-03-20
      • 2015-12-08
      • 1970-01-01
      • 2015-03-17
      • 2015-03-12
      • 2015-07-18
      • 2012-11-17
      相关资源
      最近更新 更多