У меня проблема с загрузкой изображения на 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
}