【问题标题】:Saving Files (Images) to MongoDB with MEAN stack使用 MEAN 堆栈将文件(图像)保存到 MongoDB
【发布时间】:2021-06-04 03:53:27
【问题描述】:

我正在使用基于 MongoDB 的数据库构建 Angular 应用程序。我正在尝试创建一个功能,允许用户上传文件并将它们保存在数据库中。我已经构建了拖放 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 的文件。我正在使用

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

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

我得到类似的输出

{ _id: 60b90a95e3c52664e982b480 }

没有附加记录?

【问题讨论】:

    标签: node.js angular typescript mongodb


    【解决方案1】:

    我认为更新文件时需要发送namedescuser

    【讨论】:

    • 感谢您的建议 - 我相信猫鼬模式中的所有字段默认情况下都是可选的(_id 除外)。所以我不确定这是不是?
    • 是的,你是对的。但是,如果您不发送关系字段值,您是如何检查为用户上传的图片的?
    • 不太确定我是否理解这个问题?我还没有在我的应用中实现登录逻辑,所以没有设置用户ID。
    • 啊,我明白了。那么你可以尝试使用编码base64吗?在前端,您可以将文件内容发送到base64,然后服务器将保存。如果它没有保存到数据库,我认为你的后端有一些问题。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多