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

Редактор в браузере: встраивание через iframe

Как встроить редактор A4 в веб-приложение: два адреса вашего API, три шага до рабочего редактора и что происходит внутри.

Если ваш продукт живёт в браузере, редактор можно встроить в него без установки чего-либо пользователю: страница редактора открывается внутри вашего приложения, а документ считает ядро на сервере.

Два обязательных адреса вашего API и третий, необязательный. Если у вас есть личный кабинет и файлы, оба обязательных уже существуют.

Адрес Зачем Что должен отвечать
«кто я» Узнать пользователя Принимает куки или заголовок браузера, отвечает успехом и идентификатором пользователя, иначе — отказом
«файл по идентификатору» Отдать документ По тому же удостоверению отдаёт DOCX только тому, у кого есть право. Можно отвечать и подписанной ссылкой — редактор по ней перейдёт
«создать файл» (необязательный) Открыть второму его копию Принимает байты DOCX, в ответе — идентификатор нового файла

Своей базы, учётных записей и паролей у редактора нет: пользователей и права знаете вы.

Управляющий процесс поднимается одной командой и слушает только локальный интерфейс. Первой строкой он печатает готовность.

Окно терминала
FASTDOC_CLI_BIN="$CLI" \
WEBHOST_WS_DIR=/opt/fastdoc/webhost \
node webhost/cabin-manager.mjs \
--template /opt/fastdoc/blank.docx \
--docs-dir /opt/fastdoc/cabins \
--port 8090 \
--auth-url 'https://ваш-хост/api/me' \
--attach-url 'https://ваш-хост/api/files/{id}/content'

Две переменные обязательны, и без них процесс поднимется, но работать не будет. FASTDOC_CLI_BIN — путь к процессору: это тот же $CLI, что и на странице Установка и проверка. WEBHOST_WS_DIR — полный путь к тому самому каталогу webhost, из которого запускается менеджер: по нему он находит свои файлы.

Перед запуском полезно проверить готовность площадки: doctor.mjs называет человеческим языком, чего не хватает — ядра, шаблона, занятого порта или доступности ваших адресов.

Обычный обратный прокси с одним обязательным условием: переключение на WebSocket должно проходить. Без этого редактор не свяжется с ядром.

Готовый образец для nginx лежит в поставке, в каталоге examples. Важны три вещи: передача заголовков переключения протокола, передача кук вашей авторизации и достаточный тайм-аут чтения.

В вашем интерфейсе у файла появляется пункт «Редактировать»:

<iframe src="/fastdoc/?doc=document-id"
style="width:100%;height:100%;border:0"
allow="clipboard-read; clipboard-write"></iframe>

Пользователь, вошедший в ваше приложение, попадает в редактор со своим документом. Правки возвращаются в ваш файл вашим же API.

  • У каждого пользователя своя кабинка — отдельный процесс и свой документ. Чужой документ не виден и подсунуть его нельзя.
  • Права остаются за вами. Не отдали файл — редактор не откроется. И не только на входе: раз в несколько минут редактор переспрашивает, вправе ли человек всё ещё открывать документ, который у него открыт. Отобрали права — кабинка гаснет, и человек видит ваш же ответ.
  • Правки уходят вашим API с удостоверением того же пользователя.
  • Отказ в записи виден человеку. Если вы отвечаете отказом навсегда — сессия истекла или прав больше нет, — вверху страницы появляется полоса: правки сейчас не сохраняются, работа не потеряна. Когда запись снова проходит, полоса уходит.
  • Кабинка гаснет после простоя и поднимается заново при следующем входе. Часть кабинок можно держать прогретыми заранее: тогда вход в новый документ занимает доли секунды вместо ожидания запуска процесса.

Состояние площадки видно по адресу /health: версия сборки, сколько кабинок живо, сколько отказов в записи было за последний час.

Редактор не имеет своих учётных записей и паролей: личность он берёт из вашего приложения. Поэтому запрос без вашей сессии получает отказ, а человек видит короткое объяснение — «нужен вход, войдите в систему и откройте документ снова». Это не ошибка встраивания, а нормальное поведение: если такое видит вошедший пользователь, значит до редактора не доехали куки — проверьте, что он открывается по https и на том же домене, а прокси передаёт куки.

Для этого и нужен третий, необязательный адрес — «создать файл». Не дадите его — ничего не сломается: второй человек получит честный отказ вместо копии, и проверка готовности предупредит об этом заранее.

Копия получает осмысленное имя, если ваш адрес отдачи файла присылает обычный заголовок с именем: тогда она называется «Договор №42 (копия).docx», а не датой создания.

Сколько раз за час двоим понадобился один документ, видно в том же /health. По этой цифре и стоит решать, нужно ли вам совместное редактирование вообще.

В настольном приложении сверху идёт полоса окна с именем документа и кнопками. В браузере имя документа уже написано на вкладке, и получаются два заголовка друг над другом. Поэтому вид полосы настраивается:

Значение Что делает Кому подходит
none — по умолчанию в браузере Полосы нет, сверху сразу лента Всем, кто открывает редактор в браузере
slim Полоса есть, но без имени документа Кому нужны её кнопки под рукой
full Как в настольном приложении Кому нужен прежний вид один в один

Меняется только видимость: геометрию документа считает ядро, страница не сдвигается. Сохранение при выключенной полосе остаётся во вкладке «Файл».

В поставке есть три проверки, и все запускаются одной командой.

Что проверить Чем
Готовность площадки до запуска doctor.mjs
Правильность встраивания целиком acceptance.mjs — печатает таблицу «ждали / вышло»
Поведение под нагрузкой load-test.mjs — на ваших же живых сессиях

Ноль в строке «не сошлось» у приёмки означает, что встраивание сделано правильно.

Ассистент документации

Ответ собран из документации и может быть неточным — сверяйтесь с источниками.