Прежде чем перейти на aws s3, мое приложение mern загружало и отображало изображения с использованием Reaction-Dropzone и Multer. Файлы изображений были сохранены в серверной папке «uploads». Приложение работало локально.
Моя проблема началась после того, как я развернул ее на Heroku. Для контекста, вот мой живой сайт: https://famcloud.herokuapp.com/
Теперь, когда я изменил несколько строк кода для хранения файлов в корзине aws s3, мои изображения не отображаются. t рендеринг.
Хорошая новость заключается в том, что через мою консоль я вижу, что изображения загружаются и отправляются в корзину aws s3 (а также в Db). Таким образом, проблема состоит в том, чтобы выяснить, как их визуализировать.
Я застрял в адском уроке с таким количеством видео на YouTube и статей в блогах, объясняющих, как загружать файлы в aws, но, похоже, не могу найти правильного руководства для их отображения.
Хорошо, я сейчас вернусь к коду.
К счастью, это просто два файла, где я что-то упустил.
На внутренней стороне моя фотография. Файл js в моей папке маршрутов выглядит следующим образом:
const router = express.Router();
const { Photo } = require("../../models/Photo");
const multer = require('multer');
const aws = require('aws-sdk');
const multerS3 = require('multer-s3');
const path = require('path');
const { auth } = require("../../middleware/auth");
const s3 = new aws.S3({
accessKeyId: '',
secretAccessKey: '',
Bucket: 'famcloud2'
});
function checkFileType(file, cb) {
// Allowed ext
const filetypes = /jpeg|jpg|png|gif/;
// Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images Only!');
}
}
// Multiple File Uploads ( max 4 )
const uploadsBusinessGallery = multer({
storage: multerS3({
s3: s3,
bucket: 'famcloud2',
acl: 'public-read',
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, path.basename(file.originalname, path.extname(file.originalname)) + '-' + Date.now() + path.extname(file.originalname))
}
}),
limits: { fileSize: 10000000 }, // In bytes: 2000000 bytes = 2 MB
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
}).array('galleryImage', 4);
router.post('/uploadMultiple', auth, (req, res) => {
uploadsBusinessGallery(req, res, err => {
console.log('file sent/saved to AWS: ', req.files);
if (err) {
return res.json({ success: false, err })
}
return res.json({ success: true, image: req.files.key, fileName: req.files.key })
})
});
//Here's the front-end React Component file:
import React, { useState } from 'react'
import Dropzone from 'react-dropzone';
import { CloudUploadOutlined } from '@ant-design/icons'
import Axios from 'axios';
function FileUpload(props) {
const [Images, setImages] = useState([])
const onDrop = (files) => {
let formData = new FormData();
const config = {
header: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`
}
}
formData.append("galleryImage", files[0])
//save the Image we chose inside the Node Server
Axios.post('/api/photo/uploadMultiple', formData, config)
.then(response => {
if (response.data.success) {
setImages([...Images, response.data.image])
props.refreshFunction([...Images, response.data.image])
} else {
alert('Failed to save the Image in Server')
}
})
}
const onDelete = (image) => {
const currentIndex = Images.indexOf(image);
let newImages = [...Images]
newImages.splice(currentIndex, 1)
setImages(newImages)
props.refreshFunction(newImages)
}
return (
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Dropzone
onDrop={onDrop}
multiple={false}
maxSize={800000000}
>
{({ getRootProps, getInputProps }) => (
<div className="uploadTarget"
style={{
width: '300px', height: '240px', border: '1px solid lightgray',
display: 'flex', alignItems: 'center', justifyContent: 'center',
backgroundColor: "rgba(1,1,1,0.3)", borderRadius: "10px"
}}
{...getRootProps()}
>
<input {...getInputProps()} />
<CloudUploadOutlined style={{ fontSize: '5rem', cursor: "pointer" }} />
</div>
)}
</Dropzone>
<div style={{ display: 'flex', width: '350px', height: '240px', overflowX: 'scroll' }}>
{Images.map((image, index) => (
<div onClick={() => onDelete(image)}>
<img style={{ minWidth: '300px', width: '300px', height: '240px' }} src={`http://localhost:5000/${image}`} alt={`photoImg-${index}`} />
</div>
))}
</div>
</div>
)
}
export default FileUpload```