Создать корневой каталог
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 у вас будет новая папка, содержащая все изображения из этого конкретного обращения к серверу.