Создать корневой каталог

mkdir S3Загрузить

cd S3Upload

Настройка сервера

серверная часть mkdir

бэкенд компакт-диска

инициализация npm

npm install --save aws-sdk babel-cli babel-preset-env bluebird body-parser dotenv express file-type fs multiparty nodemon path

нажмите .babelrcили создайте файл с именем .babelrc внутри внутренней папки и поместите этот код в этот файл.

{
  "presets": ["env"]
}

источник

mkdir src или создайте папку с именем src внутри внутренней папки.

источник компакт-диска

нажмите index.js

index.js

import dotenv from "dotenv";
dotenv.config();
import express from "express";
import bodyParser from "body-parser";
import as3 from "./routes/as3";
const app = express();
app.use(bodyParser.json());
app.use("/api/as3", as3);
app.get("/", (req, res) => {
  res.send("hello this is an API");
});
const port = process.env.PORT || 9090;
app.listen(port, () => console.log(`running on ${port}`));

mkdir route или создайте папку с именем route внутри папки src

переходные маршруты

нажмите as3.js

as3.js

import express from "express";
import AWS from 'aws-sdk';
import fs = from 'fs';
import fileType from 'file-type';
import bluebird from 'bluebird'
import multiparty from 'multiparty';
const router = express.Router();
AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: 'us-east-1' // us-east-1 for me
});
AWS.config.setPromisesDependency(bluebird);
const s3 = new AWS.S3();
const uploadFile = (buffer, name, type) => {
  const params = {
    ACL: 'public-read',
    Body: buffer,
    Bucket: process.env.BUCKET_NAME,
    ContentType: type.mime,
    Key: `${name}.${type.ext}`
  };
  return s3.upload(params).promise();
};
router.post("/upload", (req, res, next) => {
  const form = new multiparty.Form();
  form.parse(req, async (error, fields, files) => {
  
  if(error) res.status(500).json({ message:'could not parse form' })
  else {
      const {
        name,
        email,
       } = fields
     
      let user = { 
        name: name[0],
        email: email[0],
        photoOne: null,
        photoTwo: null,
       }
      let photosS3Names = ['photo-one', 'photo-two']
      let photosKeys = ['photoOne', 'photoTwo']             
      let photos = [files.photoOne, files.photoTwo]
     
             for(let i = 0; i < photos.length; i++) {
              if(photos[i]) {
                if(photos[i][0]) {        
                    if(photos[i][0].path) {
                      let path = photos[i][0].path;
                      if(path) {
                        const buffer = fs.readFileSync(path);
                        const type = fileType(buffer);
                        const fileName = `${email[0]}-${photosS3Names[i]}`;
                        const data = await uploadFile(buffer, fileName, type);
                        user[photosKeys[i]] = data.Location;
                      }
                    }
                }
                else {
                  res.status(500).json({ message: "Their was an error processing your images." })
                  break;
                }
              }
            }
      res.json({ user }); 
    }
  }
});
export default router;

Теперь создайте файл с именем .env в вашей бэкэнд-папке и заполните информацию о корзине.

.env

BUCKET_NAME=xxxxxx
AWS_ACCESS_KEY_ID=xxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxx

запустите свой сервер, выполнив эту команду в своем терминале
nodemon — exec babel-node src/index.js

Клиент установки

Введите .. и нажмите Enter в терминале, чтобы перейти в каталог.

создать-реагировать-клиент приложения

клиент компакт-дисков

установить npm

npm install axios --save

в package.json добавьте поле прокси, должно выглядеть примерно так

{
  "name": "projectname",
  "version": "0.1.0",
  "private": true,
  "dependencies": {},
  "proxy": "http://localhost:9090"
}

в app.js

import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {
onSelectFile = (key, e) => {
    if (e.target.files && e.target.files.length > 0) {
      const reader = new FileReader();
      reader.addEventListener('load', () => {
        if (key === "photoOne") {
          document.getElementById("photoOne").src = reader.result
        }
        if (key === "photoTwo") {
          document.getElementById("photoTwo").src = reader.result
        }
        this.setState({ [key]: reader.result, })
      }
      );
      reader.readAsDataURL(e.target.files[0]);
    }
};
uploadToS3 = () => {
    const formData = new FormData();
    formData.append('name', 'jon doe');
    formData.append('email', '[email protected]');
    formData.append('photoOne', this.state.photoOne);
    formData.append('photoTwo', this.state.photoTwo);
    axios.post(
      "/api/as3/upload", formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    )
      .then(res => console.log(res))
      .catch(err => console.log(err))
  }
render() {
    return (
      <div>
        <input
          accept="image/*"
          name="photoOne"
          type='file'
          onChange={(e) => this.onSelectFile('photoOne', e)}
        />
        <input
          accept="image/*"
          name="photoTwo"
          type='file'
          onChange={(e) => this.onSelectFile('photoTwo', e)}
        />
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gridGap: 10 }} >
          <div style={{ overflow: 'hidden' }}> <img id="photoOne" src="" /> </div>
          <div style={{ overflow: 'hidden' }} > <img id="photoTwo" src="" /> </div>
          <button placeholder="upload" onClick={this.uploadToS3}> Upload </button>
        </div>
      </div>
    );
  }
}
export default App;

Ваш ответ должен включать пользовательский объект со всеми данными формы, которые мы передали на сервер. Два ключа photoOne и photoTwo будут иметь URL-адреса S3.

Вот и все.

Пример варианта использования

То, что я представил выше, позволит вам загружать несколько фотографий за один вызов сервера и хранить эти фотографии в корзине S3. Если вы хотите, чтобы каждая группа фотографий находилась в своей папке, вы должны передать уникальную строку в fileName , разделенную символом /.

const fileName = `${fields.uniquekey}/${fields.name}`;

Теперь в корзине S3 у вас будет новая папка, содержащая все изображения из этого конкретного обращения к серверу.