Как использовать FilePond с Node.js

автор vadim


Загрузка файлов — обычная потребность облачных приложений. FilePond — это надежный проект с открытым исходным кодом, который предлагает сложную обработку файлов и оболочки для многих фреймворков JavaScript, таких как React и Svelte.

В этой статье представлен обзор обработки загрузки файлов с помощью FilePond и серверной части Node.js и Express.

Почему FilePond?

Для этой задачи доступно множество библиотек, но FilePond чрезвычайно прост в использовании и справляется с такими тонкостями, как оптимизация изображений, без дополнительной настройки. Более того, это дает разработчику четкий процесс на стороне сервера.

В сочетании с поддержкой Angular, jQuery, React, Vue и Svelte, а также множеством плагинов, таких как предварительный просмотр изображений и изменение размера, FilePond должен быть в верхней части вашего списка опций при рассмотрении загрузки файлов.

Настройте проект FilePond

Начнем с создания проекта для хранения примера кода. Создайте каталог и назовите его /filepond. Теперь перейдите в каталог в командной строке и введите npm init. Примите все значения по умолчанию.

Теперь установите сервер Express с помощью npm install express. Затем создайте файл index.html и поместите его в корневой каталог проекта. Обновите новый файл содержимым листинга 1.

Листинг 1. Начальный index.html

<html>
<head>
  <link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet" />
  <script src="https://unpkg.com/filepond/dist/filepond.js"></script>
</head>
<body>
  <input type="file">
</body>
<script>
  const inputElement = document.querySelector('input[type="file"]');
  const pond = FilePond.create( inputElement );
</script>
</html>

Листинг 1 начинается с импорта стиля и кода FilePond из CDN unpkg. Вы также можете интегрировать его через npm и инструмент сборки или импортировать напрямую.

Разметка состоит только из ввода файла. Наконец, сценарий внизу получает ссылку на входной файл, а затем использует API FilePond для создания нового экземпляра FilePond с входным элементом. FilePond.create( inputElement ).

Теперь мы добавим скрипт для запуска приложения. Измените файл package.json, включив в него строку 7 из листинга 2.

Листинг 2. Добавление сценария разработки

{
  "name": "filepond",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  }
}

Убедитесь, что nodemon установлен глобально, набрав nodemon -v из CLI. Если он не найден, установите его с помощью npm install -g nodemon.

Теперь вы можете запустить приложение, введя npm run dev в корне проекта.

Пока приложение работает, вы можете посетить простую стартовую страницу, открыв в браузере http://localhost:43000/.

Вас встретит простой компонент ввода файлов. Хотя FilePond еще не привязан к серверной части, вы можете выбрать файл из локальной файловой системы, нажав «Обзор» или перетащив файл на компонент FilePond. FilePond покорно поставит его в очередь.

Обработка загрузки файла

Первый шаг во взаимодействии с серверной частью — сообщить FilePond, где он находится. FilePond может обрабатывать любой URL-адрес. В нашем случае мы собираемся использовать относительный путь из того же домена. Если вы используете абсолютный URL-адрес другого домена, помните, что в игру вступит CORS.

Измените сценарий в index.html, включив в него конфигурацию, показанную в листинге 3.

Листинг 3. Установка URL-адреса сервера

<script>
  const inputElement = document.querySelector('input[type="file"]');
  const pond = FilePond.create( inputElement );
  pond.setOptions({
    server: "/upload"
  })
</script>

Листинг 3 сообщает FilePond отправить (через POST) биты файла на относительный URL-адрес /upload. Давайте подготовим простой обработчик на сервере для проверки попадания в конечную точку. Добавьте код из листинга 4 в файл index.js.

Листинг 4. Сопоставление /upload POST

app.post("/upload", function(req, res){
  console.log("BEGIN /upload");
})

Теперь вернитесь в браузер и обновите страницу. Теперь, когда вы загружаете файл, вы можете убедиться, что к конечной точке осуществляется доступ, просмотрев журнал сервера и просмотрев выходные данные «BEGIN /upload».

Сохранение временного файла

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

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

В этом примере будет использоваться библиотека Formidable для обработки составного POST, отправляемого FilePond. Formidable — это зрелая и функциональная библиотека, достаточно гибкая, чтобы можно было писать собственные обработчики потоков. Например, если вы хотите сохранить файл в базе данных, вы можете самостоятельно обрабатывать фрагменты файла и передавать их в хранилище данных.

Для этой демонстрации мы просто запишем временный файл на диск. Начните с установки Formidable: остановите сервер (если он работает) и введите npm install formidable. Теперь вы можете перезапустить сервер.

Перейдите в index.js и импортируйте библиотеку, вставив эту строку в начало файла:

const formidable = require('formidable');

Затем обновите index.js, используя листинг 5.

Листинг 5. Принятие временного файла

app.post("/upload", function(req, res){
  console.log("BEGIN /upload");
  const form = formidable({ multiples: false });

  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    let theFile = files.filepond.path;
    console.log("theFile: " + theFile);

    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end(theFile);
  });  
})

С Formidable принятие файла происходит безболезненно. Если вы теперь загрузите файл через веб-интерфейс, вы увидите в своем журнале, что файл был записан в местоположение временного файла по умолчанию. Например, в моей локальной системе это C:\Users\mtyson\AppData\Local\Temp\.

Вы можете открыть файл и убедиться, что это именно тот файл, который вы отправили.

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

Для производственного использования вам понадобится уровень косвенности, при котором вы сохраняете файл и создаете уникальный идентификатор, который вы связываете с путем к файлу. Для наших целей мы просто будем использовать путь к файлу.

Завершение загрузки файла

Теперь вернемся к клиенту. Обернем загрузчик в форму и отправим, а также подумаем, куда сохранить файл для долгосрочного хранения. Поскольку форма отправляет только путь (или уникальный идентификатор) файла, ее можно легко обработать как запрос AJAX с JSON. Мы не упростим задачу и воспользуемся формой отправки для нашего примера (листинг 6).

Листинг 6. Форма загрузки

<body>
  <form style="display:grid;" action="/save" method="POST">
    <input type="file">
    <button type="submit" onclick="">Save It</button>
  </form>
</body>

Теперь при нажатии кнопки будет отправлен путь к файлу с меткой по умолчанию «filepond» (это можно настроить). В этом случае мы отправляем информацию в /save через POST.

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

Чтобы обработать отправку, вернитесь в index.js и используйте промежуточное программное обеспечение Express с urlencoded:

app.use(express.urlencoded({ extended: true }));

Теперь вы готовы получить информацию о файле. Добавьте обработчик, показанный в листинге 7.

Листинг 7. Получение сохранения

app.post("/save", function(req, res){
  console.log("BEGIN /save");
  console.log(`req: ${JSON.stringify(req.body)}`);
})

Когда обработчик из листинга 7 установлен, вы должны увидеть журналирование, подтверждающее получение информации. Логирование будет выглядеть примерно так:

req: {"filepond":"C:\\Users\\mtyson\\AppData\\Local\\Temp\\upload_28331577a229fe48443275b2655a1abe"}

Теперь вы можете прочитать файл с диска и делать с ним все, что захотите. Его можно прочитать с диска с помощью встроенного в Node модуля fs, как показано в листинге 8.

Листинг 8. Чтение временного файла с диска

const fs = require('fs');
//...
let fileData = fs.readFileSync(req.body.filepond);

В листинге 8 создается буферный объект файла. Вы можете записать это в другое место файловой системы (также используя модуль fs), в корзину Amazon S3 или в базу данных, например MongoDB.

Например, в MongoDB вы можете взять буфер как есть и записать его в поле следующим образом:

require('mongodb').Binary(fileData)

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

Добавить средство предварительного просмотра изображений в приложение очень просто, как показано в листинге 9.

Листинг 9. Плагин предварительного просмотра изображений

<head>
  ...
  <script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.js"></script>
  <link href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css" rel="stylesheet">
</head>
<body>
 ...
 FilePond.registerPlugin(FilePondPluginImagePreview);
 ...
</body>

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

Рисунок 1. Средство предварительного просмотра изображений

предварительный просмотр файлового пруда ИДГ

Как вы видели, FilePond предоставляет вам современный компонент для загрузки файлов с простым в использовании API. Также доступно множество других плагинов FilePond, включая полноценный редактор изображений (через интеграцию с Pintura/Doka).

Дальше читайте это:

  • Облачные вычисления больше не являются пустяком
  • Что такое генеративный ИИ? Искусственный интеллект, который создает
  • Программирование с помощью ИИ: советы и лучшие практики от разработчиков
  • Python пытается удалить GIL и повысить параллелизм
  • 7 причин, по которым Java по-прежнему хороша
  • Война за лицензирование открытого исходного кода окончена

Related Posts

Оставить комментарий