【问题标题】:Display images from aws s3 using react dropzone and multer S3使用 react dropzone 和 multer S3 显示来自 aws s3 的图像
【发布时间】:2020-08-10 12:01:06
【问题描述】:

在切换到 aws s3 之前,我的 mern 应用正在使用 react-dropzone 和 multer 上传和显示图像。图像文件保存在服务器端的“上传”文件夹中。该应用程序在本地运行良好。

我在 Heroku 上部署后就开始出现问题。对于上下文,这是我的实时站点:https://famcloud.herokuapp.com/

现在我已经更改了几行代码以将文件存储在 aws s3 存储桶中,我的图像无法呈现。

好消息是,通过我的控制台,我可以看到图像正在上传并发送到 aws s3 存储桶(以及 Db)。所以问题是弄清楚如何渲染它们。

我被如此多的 youtube 视频和博客文章困在教程地狱中,这些视频和博客文章解释了如何将文件上传到 aws,但似乎找不到正确的指导来显示它们。

好吧,我现在来看看代码。

幸运的是,我遗漏了两个文件。

在后端,我的 Routes 文件夹中的 photo.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```





【问题讨论】:

    标签: node.js reactjs amazon-s3 mern photo-gallery


    【解决方案1】:

    .success 似乎有问题,但我看不出您的代码有任何本质上的错误。我变了

                    if (response.data.success) {
    
    

                    if (response) {
    

    但它工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 2022-01-14
      • 2023-03-27
      • 2021-09-07
      • 1970-01-01
      相关资源
      最近更新 更多