Загрузка файлов в хранилище объектов с помощью Node.js

Хранилище объектов – удобный и масштабируемый способ хранения и обслуживания статических ресурсов, таких как аудио, изображения, текст, PDF-файлы и другие типы неструктурированных данных. Облачные провайдеры предлагают хранилища объектов в дополнение к традиционным локальным или блочным хранилищам, которые используются для хранения динамических файлов приложений и баз данных.

Читайте также: Сервисы хранения объектов и блочные сервисы хранения: краткий обзор

Данный мануал поможет создать приложение Node.js, которое будет выгружать файлы в хранилище объектов путем отправки формы в интерфейсе веб-сайта.

Требования

  • Хранилище объектов, access key и secret key.
  • Установленные Node.js и npm. Чтобы установить правильную версию, посетите эту ссылку.

Добавление ключей

Для подключения к хранилищу объектов можно использовать AWS SDK для JavaScript в Node.js.

Сначала нужно создать файл учетных данных и поместить в него access key и secret key, который вы получили при создании своего хранилища. Файл будет находиться в ~/.aws/credentials на Mac и Linux или C:\Users\USERNAME\.aws\credentials в Windows. Если ранее вы уже сохранили учетные данные AWS, вы можете прочитать о поддержке нескольких наборов учетных данных здесь.

Откройте командную строку, перейдите в каталог Users как пользователь sudo и создайте файл с расширением .aws по имени credentials.

sudo mkdir .aws && touch .aws/credentials

Откройте файл и вставьте в него такой код (заменив your_access_key и your_secret_key своими данными).

[default]
aws_access_key_id=your_access_key
aws_secret_access_key=your_secret_key

Теперь доступ к хранилищу через AWS SDK будет аутентифицирован, и вы можете перейти к созданию приложения.

Установка зависимостей Node.js

Для начала создайте каталог, в который вы хотите поместить приложение Node.js, и перейдите в этот каталог. В этом мануале проект будет храниться в node-app в каталоге sites.

mkdir sites/node-app && cd sites/node-app

Создайте файл package.json для проекта. Вставьте в него такой код:

{
"name": "node-app",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"license": "MIT"
}

Этот базовый файл package.json определяет имя, номер версии и лицензию вашего приложения. Поле scripts позволяет запустить сервер Node.js, набрав npm start вместо node server.js.

Команда npm install установит все зависимости:

npm install aws-sdk express multer multer-s3

После запуска этой команды файл package.json должен обновиться. Эти зависимости помогут нам подключиться к API хранилища объектов, создать веб-сервер и обрабатывать загрузки файлов.

  • aws-sdk — AWS SDK для JavaScript позволит вам получить доступ к S3 через JavaScript API.
  • express – это веб-фреймворк, который позволит быстро и эффективно настроить сервер.
  • multer – это промежуточное программное обеспечение, которое будет обрабатывать загрузку файлов.
  • multer-s3 – расширяет загрузку файлов в хранилище объектов S3.

Теперь можно настроить сервер и фронт-энд.

Примечание: По умолчанию в текущих версиях Node команда npm install сохраняет зависимости в файле package.json. Если вы используете более старую версию Node, вам нужно будет добавить флаг —save в команду npm install, чтобы обеспечить обновление пакета package.json.

Фронт-энд приложения

Для начала нужно создать файлы видов приложения. Это то, что пользователь увидит на фронт-энде. Создайте в своем проекте каталог public с файлами index.html, success.html и error.html. Все три этих файла будут иметь представленный ниже скелет HTML с разным содержимым в body. Добавьте следующий код в каждый файл.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Object Storage Tutorial</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- contents will go here -->
</body>
</html>

В файл error.html добавьте в body сообщение об ошибке:

...
<h1>Something went wrong!</h1>
<p>File was not uploaded successfully.</p>
...

В файл success.html добавьте в body сообщение о том, что файлы загружены успешно:

...
<h1>Success!</h1>
<p>File uploaded successfully.</p>
...

В index.html нужно создать форму HTML с multipart/form-data. Она будет состоять из input и кнопки отправки.

...
<h1>Object Storage Tutorial</h1>
<p>Please select a file and submit the form to upload an asset to your object storage.</p>
<form method="post" enctype="multipart/form-data" action="/upload">
<label for="file">Upload a file</label>
<input type="file" name="upload">
<input type="submit" class="button">
</form>
...

Теперь создайте файл style.css и добавьте в него простой стиль CSS.

html {
font-family: sans-serif;
line-height: 1.5;
color: #333;
}
body {
margin: 0 auto;
max-width: 500px;
}
label,
input {
display: block;
margin: 5px 0;
}

Эти три файла создают форму загрузки, которая будет основной страницей этого небольшого приложения, а также сообщения о состоянии загрузки файлов пользователя.

Настройка среды Express

Все файлы для фронт-энда приложения готовы, но в настоящее время нет настроенного сервера для их просмотра. Настройте сервер Node и фреймворк Express.

В корневом каталоге проекта создайте файл server.js. Сначала загрузите четыре зависимости приложения с помощью require(). Направьте приложение через экземпляр app.

// Load dependencies
const aws = require('aws-sdk');
const express = require('express');
const multer = require('multer');
const multerS3 = require('multer-s3');
const app = express();

Поскольку фронт-энд находится в каталоге public, добавьте его в конфигурацию:

...
// Views in public directory
app.use(express.static('public'));

Файлы index.html, success.html и error.html нужно направить в корень сервера.

...
// Main, error and success views
app.get('/', function (request, response) {
response.sendFile(__dirname + '/public/index.html');
});
app.get("/success", function (request, response) {
response.sendFile(__dirname + '/public/success.html');
});
app.get("/error", function (request, response) {
response.sendFile(__dirname + '/public/error.html');
});

В конце нужно определить порт, который будет прослушивать сервер. В этом примере используется 3001, но вы можете установить любой другой доступный порт.

...
app.listen(3001, function () {
console.log('Server listening on port 3001.');
});

Сохраните файл server.js и запустите сервер. Для этого нужно выполнить команду node server.js или npm start (сокращение, которое вы настроили ранее в файле package.json).

npm start
> node server.js
Server listening on port 3001.

Откройте в браузере ссылку http://localhost:3001, и вы увидите форму загрузки, поскольку файл index.html является корневым для сервера.

Object Storage Tutorial
Please select a file and submit the form to upload an asset to your object storage.

Также вы можете проверить ссылки http://localhost:3001/success и http://localhost:3001/error, чтобы убедиться, что эти страницы работают.

Загрузка файла в хранилище с помощью Multer

Теперь, когда серверная среда работает корректно, нужно интегрировать формы с Multer и Multer S3 для загрузки файла в хранилище объектов.

Вы можете использовать метод new aws.S3()  для подключения к клиенту Amazon S3. Для использования вашего хранилища объектов нужно установить новую конечную точку. В данном мануале используется условная точка nyc3.

Перейдите в начало файла server.js и вставьте в него следующий код после объявления const:

...
const app = express();
// Set S3 endpoint to Object Storage
const spacesEndpoint = new aws.Endpoint('nyc3.your-object-storage.com');
const s3 = new aws.S3({
endpoint: yourEndpoint
});

Используя пример из документации multer-s3, создайте функцию upload, установив в свойстве bucket уникальное имя вашего хранилища. Указав public-read в acl, вы сделаете все файлы в хранилище общедоступными; оставив этот параметр по умолчанию, вы сделаете файлы приватными, и они не будут доступны из Интернета.

...
// Change bucket property to your Object Storage name
const upload = multer({
storage: multerS3({
s3: s3,
bucket: 'your- object-storage-here',
acl: 'public-read',
key: function (request, file, cb) {
console.log(file);
cb(null, file.originalname);
}
})
}).array('upload', 1);

Функция upload готова, остался последний шаг – соединить форму загрузки с кодом для отправки файла и маршрутизации пользователя. Перейдите в конец файла server.js и вставьте этот код прямо над методом app.listen().

...
app.post('/upload', function (request, response, next) {
upload(request, response, function (error) {
if (error) {
console.log(error);
return response.redirect("/error");
}
console.log('File uploaded successfully.');
response.redirect("/success");
});
});

Когда пользователь нажимает кнопку отправки, в /upload отправляется POST запрос. Node прослушивает этот POST и вызывает функцию upload(). Если обнаружена ошибка, условный оператор перенаправляет пользователя на страницу /error. Если запрос обработан успешно, пользователь будет перенаправлен на страницу /success, и файл будет загружен в ваше хранилище объектов.

Полный код файла server.js выглядит так:

// Load dependencies
const aws = require('aws-sdk');
const express = require('express');
const multer = require('multer');
const multerS3 = require('multer-s3');
const app = express();
// Set S3 endpoint to Object Storage
const spacesEndpoint = new aws.Endpoint('nyc3.your-object-storage.com');
const s3 = new aws.S3({
endpoint: yourEndpoint
});
// Change bucket property to your Space name
const upload = multer({
storage: multerS3({
s3: s3,
bucket: 'your-object-storage-here',
acl: 'public-read',
key: function (request, file, cb) {
console.log(file);
cb(null, file.originalname);
}
})
}).array('upload', 1);
// Views in public directory
app.use(express.static('public'));
// Main, error and success views
app.get('/', function (request, response) {
response.sendFile(__dirname + '/public/index.html');
});
app.get("/success", function (request, response) {
response.sendFile(__dirname + '/public/success.html');
});
app.get("/error", function (request, response) {
response.sendFile(__dirname + '/public/error.html');
});
app.post('/upload', function (request, response, next) {
upload(request, response, function (error) {
if (error) {
console.log(error);
return response.redirect("/error");
}
console.log('File uploaded successfully.');
response.redirect("/success");
});
});
app.listen(3001, function () {
console.log('Server listening on port 3001.');
});

Остановите сервер Node, нажав Control+C, и перезапустите его, чтобы обновить параметры:

npm start

Перейдите в корень проекта, выберите файл и отправьте форму. Если все настроено правильно, вы будете перенаправлены на страницу success, и в хранилище объектов появится новый общедоступный файл.

Success!
File uploaded successfully.

Если имя загруженного файла — test.txt, он будет доступен по URL-адресу https://your-object-storage-here.nyc3.your-object-storage.com/test.txt.

Общими причинами неудачной транзакции являются неправильно расположенный файл учетных данных, неправильные учетные данные или имя корзины.

Заключение

Теперь у вас есть приложение на Node.js и Express для отправки файлов в хранилище объектов.

Получившееся приложение – отличный старт для настройки хранилища объектов. Однако прежде чем запустить приложение в производство, необходимо принять дополнительные меры предосторожности (например, настроить аутентификацию).

Читайте также:

Tags: