Можно ли с помощью Service Worker перехватить и изменить http запрос?

Можно ли с помощью Service Worker перехватить http запрос и изменить его тело или заголовки.
  • Вопрос задан
  • 1394 просмотра
Решения вопроса 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Одна из задач Service Worker - именно программируемый прокси на стороне клиента.
То есть на Ваш вопрос "можно?" - я бы ответил, да - это одна из основных функций Service Worker.
Но есть одно но, Service Worker работает только с тем доменном, с которого загружен его код. То есть можно перехватывать только запросы к своему домену. Притом, данная функция доступна только для не кросдоменных запросов (тех что идут со страниц своего же домена). Стоит так же упомянуть экспериментальное событие foreignfetch упомянутое в сводке фич chrome на google developers за сентябрь "16 - оно позволяет перехватывать обращение к своему домену с чужих ресурсов, но о нем не знает ни mdn, ни caniuse - как следствие событие потенциально работает только в chrome 54+.
Так же стоит учитывать, что поддержка Service Worker хорошо реализована только в Chrome и Firefox. В Edge появилась с 17 версии (вышедшей вместе с win10 April"18 update), в safari тоже появилась недавно (11.1 - десктоп, 11.4 - iOS)

Если это все устраивает, то:
Читаем эту статью на mdn: https://developer.mozilla.org/ru/docs/Web/API/Serv...
Так как из стать выше для Вашей задачи можно почерпнуть только работу с событием fetch (с событием foreignfetch работаем аналогично) и большинство примеров нацелены на программируемый кэш, а для подделки запросов нужно генерировать свой объект Responce - читаем эту статью: https://developer.mozilla.org/en-US/docs/Web/API/R... (only English)
Так же читаем про Request: https://developer.mozilla.org/en-US/docs/Web/API/R...

Вся суть будет сводится примерно к следующему коду Service Worker:
self.addEventListener('fetch', event => {
  const {request} = event;
  // обрабатываем request чтоб понять, что от нас хотят
  //...
  if(/* условие, что запрос нужно подменить */) {
    event.respondWith(new Response('Hello world', /* вместо строки можно Blob или ArrayBuffer */ {
      headers: { 'Content-Type': 'text/plain' }
    }));
  } else {
    event.respondWith(fetch(request)); // если не наш случай, отправляем запрос на сервер,
    // тут так же можно заморочится с кэшем
  }
});


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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
summer Ярославль
от 100 000 до 140 000 ₽
КРАФТТЕК Санкт-Петербург
от 60 000 до 80 000 ₽
19 апр. 2024, в 23:00
5000 руб./за проект
19 апр. 2024, в 20:43
20000 руб./за проект