Nodejs загрузка изображения в S3, изображение не сохранено правильно - PullRequest
0 голосов
/ 03 августа 2020

У меня проблема с загрузкой изображения на S3. Изображение загружено правильно, но когда я его просматриваю; он отображается как пустой квадрат. Я добавляю связанный код как для внешнего, так и для внутреннего интерфейса для справки, но соответствующий код является последней функцией в бэкэнде. ImageManager.prototype.upload

HTML:

<input class="d-none" type="file" (change)="onLogoChanged($event)" #fileInput>

        <button mat-raised-button
                type="file"
                class="btn btn-just-icon btn-link"
                matTooltip="Change image" [matTooltipPosition]="'above'"
                (click)="fileInput.click()"
        >

Обработчик:

  onLogoChanged(event) {
    // here i save a reference to the selected file
    this.file = _.get(event, 'target.files[0]');
  }

При загрузке на сервер

updateLogo(file: File): Promise<any> {
    const formData = new FormData();
    formData.append('logo', file, file.name);
    return this.http.put(`${environment.CLOUD_API_URL}/accounts/logo`, formData)
      .toPromise();
  }

На backend:

const multer = require('multer');
const upload = multer({});

router.put('/logo', upload.single('logo'), expressAsync(async (req, res) => {
  const logo = await accountService.updateLogo(req.accountId, req.file);
  res.status(httpStatus.OK).send({logo});
}));

AccountService.prototype.updateLogo = async function (accountId, file) {
  const {mimetype: mimeType = '', fieldname: fileName = ''} = file;
  const fileType = _.last(_.split(mimeType,'/'));
  const fileKey = `${accountId}/${fileName}.${fileType}`;

  // This I'm 100% sure I should be doing. 
  // The encoding type that comes from the frontend for the logo file is "7bit". 
  // I just passed file.buffer and encoding = 7bit  to S3, the image becomes corrupted; 
  // that's why I went with base64, but I'm still having the issue where the image does not get saved correctly.
  const fileData = file.buffer.toString('base64');

  const logoImage = await imageManager.upload(fileKey, fileData, 'base64', mimeType);
  await this.updateAccount(accountId, {logoImage});

  return `${logoImage.Location}?etag=${logoImage.ETag}`;
};

// это то, что загружается в S3; Вероятно, здесь и заключается проблема:

ImageManager.prototype.upload = async function (fileKey, body, encoding, contentType) {
  const params = {
    Bucket: config.get('aws.s3.storageBucket'),
    Key: fileKey,
    Body: body,
    ContentEncoding: encoding,
    ContentType: contentType,
    ACL: 'public-read',
    StorageClass: 'STANDARD'
  };

  return s3.upload(params).promise();
};

Для справки этот мой файловый объект в бэкэнде:

{
  "fieldname": "logo",
  "originalname": "favicon-black.png",
  "encoding": "7bit",
  "mimetype": "image/png",
  "buffer": {
    "type": "Buffer",
    "data": [
      194,
      137,
      80,
      ...
    ]
  },
  "size": 49998
}
...