首页 > 解决方案 > 使用 MEAN 堆栈将文件(图像)保存到 MongoDB

问题描述

我正在使用基于 MongoDB 的数据库构建一个角度应用程序。我正在尝试创建一个功能,允许用户上传文件并将它们保存在数据库中。我已经构建了拖放 UI,并相信 Angular 发送.png正确,但是,保存在 MongoDB 中的对象不包含任何内容(由调试和 DB 的 GUI 检查确认)。

任何想法为什么我的 API 会丢失它正在保存的文件的内容?

在此处输入图像描述

fileDrop.component.ts

@Component({
  selector: 'app-data-select',
  templateUrl: './data-select.component.html',
  styleUrls: ['./data-select.component.scss']
})
export class DataSelectComponent implements OnInit {
  constructor(private dataSelectService: DataSelectService) { }
  ngOnInit(): void {}
  public files: NgxFileDropEntry[] = [];

  public dropped(files: NgxFileDropEntry[]) {
    this.files = files;
    for (const droppedFile of files) {

        const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
        fileEntry.file((file: File) => {

          const formData: any = new FormData()
          formData.append('img', file, droppedFile.relativePath)

          // Debug HERE - file is correctly populated 

          this.dataSelectService.register(file).subscribe(res => {
            // Debug HERE - file just returns an Object ID
          });
        });
    }
  }

}

dataSelect.service.ts

@Injectable({
  providedIn: 'root'
})
export class DataSelectService {

  constructor(private http: HttpClient) { }

  register(data: File): Observable<File> {
    return this.http.post<File>('/api/image', data);
  }
}

在后端 -

image.model.ts

const imageSchema = new mongoose.Schema({
  name: String,
  desc: String,
  user: String,
  img:
  {
    data: Buffer,
    contentType: String
  }
});

const Image = mongoose.model('Image', imageSchema);

export default Image;

然后控制器功能保存到数据库:

  insert = async (req, res) => {
    try {
      const obj = await new this.model(req.body).save();
      res.status(201).json(obj);
    } catch (err) {
      return res.status(400).json({ error: err.message });
    }
  }

我怀疑数据的格式。在我在网上看到的大多数示例中,人们倾向于使用中间本地文件存储(通常使用 Multer),因此 API 接收图像,然后将其保存到本地系统,然后再将其上传到数据库。

我不明白你为什么要增加额外的复杂性?

其他讨论倾向于关注用于保存文件的 GRIDFS 数据类型。但是,我相信这仅适用于 > 16MB 的文件。我正在使用 < 1MB 的图像,所以我认为这无关紧要。但是是否有我应该使用的特殊数据类型或某种编码?

但是,即使我在将数据写入数据库之前拦截数据,使用 -

imageSchema.pre('save', function (next): void {
  const image = this;
  console.log(image);
  next();
});

我得到一个像

{ _id: 60b90a95e3c52664e982b480 }

没有附加记录?

标签: node.jsangulartypescriptmongodb

解决方案


我认为您需要在更新文件时发送name, 。descuser


推荐阅读