На работе для сервис воркера в PWA используем workbox.
Картинки не отправляем, но разных форм много. И как раз схожий кейс.
import { NetworkOnly } from 'workbox-strategies';
import { BackgroundSyncPlugin } from 'workbox-background-sync';
import { registerRoute } from 'workbox-routing';
import { StatusCodes } from 'http-status-codes';
const bgSyncPlugin = new BackgroundSyncPlugin('APIRequestsQueue', {
// Повторять попытку отправить запрос в течение 8 часов (указывается в минутах)
maxRetentionTime: 480,
});
['POST', 'PUT', 'PATCH', 'DELETE'].forEach((method) => {
registerRoute(
({ url }) => url.pathname.startsWith('/v1'),
new NetworkOnly({
plugins: [
{
...bgSyncPlugin,
/**
* Этот обработчик будет вызван, когда не удалось выполнить запрос.
* Информация о запросе будет помещена в очередь и запрос
* выполнится при подключении к сети.
* Возвращаем статус 202 Accepted, чтобы в приложении
* можно было понять из-за чего не удалось выполнить запрос
* и отреагировать должным образом.
*/
handlerDidError() {
return Promise.resolve(new Response(null, {
status: StatusCodes.ACCEPTED,
}));
},
},
],
}),
method,
);
});
Таким образом достигается такой порядок действий:
1. Заполняем форму
2. Исчезает интернет
3. Жмём кнопку ОТПРАВИТЬ
4. Сервис воркер сохраняет данные запроса в кеше с именем APIRequestsQueue и возвращает 202 код
5. Сеть появляется
6. Запросы из кеша APIRequestsQueue уходят по очереди в фоне, без участия пользователя