Отобразите изображения из aws s3, используя реакционную зону и мультер S3 - PullRequest
0 голосов
/ 27 апреля 2020

Прежде чем перейти на 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```





...