Перейти к основному содержимому

Работа с сервером

RichText работает полностью в браузере и не требует бэкенда для редактирования или сохранения контента. Ваше приложение может хранить содержимое редактора там, где вам удобно. Единственная функция, которая выигрывает от наличия сервера, — загрузка изображений: когда пользователь вставляет изображение в документ, RichText может либо встроить файл непосредственно в контент, либо отправить его на HTTP-эндпоинт и сохранить ссылку на него.

В этом руководстве объясняется:

  • что происходит по умолчанию, если сервер загрузки не настроен
  • точный HTTP-контракт, который должен реализовать сервер
  • как RichText использует URL, возвращённый сервером
  • как протестировать функцию на демо-бэкенде

Поведение по умолчанию: встроенные изображения

Если вы не задаёте свойство imageUploadUrl, RichText использует встроенные изображения. Когда пользователь вставляет изображение, RichText читает файл в браузере, кодирует оригинальный файл как data:image/...;base64,... URL и записывает его непосредственно в контент редактора в виде атрибута src элемента <img/>. RichText ограничивает отображаемый размер, чтобы он вписывался в рамку 1024×800 пикселей, используя атрибуты width/height, но встроенные байты — это оригинальный файл в полном разрешении: клиент не уменьшает и не перекодирует его.

Это работает без какого-либо бэкенда и удобно для быстрых демонстраций, но имеет очевидные ограничения:

  • закодированные байты хранятся внутри документа, поэтому сохранённый HTML растёт с каждым изображением
  • одно и то же изображение в двух документах хранится дважды — общего ресурса для дедупликации нет
  • поскольку байты не являются отдельным ресурсом, сервер не может раздавать их через CDN или постобрабатывать (изменять размер, перекодировать, сканировать)
  • встроенные изображения не сохраняются при встроенном экспорте в форматы DOCX/PDF — если вы используете экспорт, настройте сервер загрузки, чтобы изображения ссылались на внешний URL

Напишите свой сервер

В продакшн-приложениях укажите RichText адрес сервера с помощью imageUploadUrl:

new richtext.Richtext("#root", {
imageUploadUrl: "https://example.com/upload"
// другие свойства конфигурации
});

Минимальный эндпоинт загрузки должен:

  1. Принимать POST-запрос в формате multipart/form-data с полем файла, названным upload.
  2. Валидировать файл (допустимые типы, максимальный размер).
  3. Сохранять файл туда, откуда браузер пользователя сможет его получить (локальный диск, раздаваемый по HTTP, S3, CDN и т.д.).
  4. При необходимости изменять размер или иным образом обрабатывать изображение.
  5. Возвращать JSON-объект, содержащий status: "server", поле value со публичным URL сохранённого файла, а также width и height изображения в пикселях.

Что отправляет клиент

Когда задан imageUploadUrl, RichText отправляет выбранный файл непосредственно на этот URL (не добавляет /images или другой путь), поэтому передаваемый URL является полным адресом для POST-запроса.

Запрос использует стандартную загрузку через HTML-форму:

  • Метод: POST
  • Content-Type: multipart/form-data
  • Тело: одно поле файла с именем upload

Что ожидает клиент в ответ

Сервер должен ответить JSON-объектом. RichText читает следующие поля:

ПолеТипЗначение
statusstringМаркер успеха — возвращайте "server" при успешной загрузке. Загрузчик использует это поле, чтобы отличить завершённую загрузку от неудачной; любое другое значение (например, "error") помечает загрузку как неудачную. Само вставляемое изображение строится из полей value, width и height.
valuestringURL сохранённого изображения. RichText записывает эту строку дословно в документ как атрибут src вставляемого <img/>.
widthintegerШирина вставляемого изображения в пикселях.
heightintegerВысота вставляемого изображения в пикселях.

Успешный ответ

При успешной загрузке возвращается URL сохранённого изображения и его размеры:

{
"status": "server",
"value": "https://cdn.example.com/uploads/abc123.png",
"width": 320,
"height": 207
}

Неудачная загрузка

При неудачной загрузке возвращается любой статус, отличный от "server":

{
"status": "error"
}

Раздача загруженного изображения

URL из поля value — единственная связь между загрузкой и всеми последующими чтениями документа. RichText вставляет URL непосредственно в документ, поэтому любой клиент, открывающий сохранённый контент (сам редактор, экспорт, опубликованная страница), получает изображение по этому URL через обычный GET-запрос.

Это означает:

  • URL должен быть доступен из браузера пользователя, что обычно означает, что он должен быть абсолютным
  • хост может отличаться от эндпоинта загрузки (например, вы можете принимать загрузки на своём сервере и возвращать URL CDN или объектного хранилища)
  • если хост изображения находится на другом источнике, убедитесь, что он разрешает странице загружать изображение (CORS или просто открытый доступ для чтения)
  • сервер должен поддерживать работу этого URL до тех пор, пока на него ссылаются документы; RichText не кэширует и не копирует байты

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

Тестирование на демо-сервере

Для тестирования функции доступен рабочий бэкенд, реализующий этот контракт:

new richtext.Richtext("#root", {
imageUploadUrl: "https://docs.dhtmlx.com/richtext-backend/images"
// другие свойства конфигурации
});

Демо-сервер изменяет размер больших изображений, сохраняет их на диск и возвращает URL, которые сам же и раздаёт. Он предназначен только для ознакомления и демонстраций. Не используйте его в продакшн-редакторах.

Связанные статьи: