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

Можно ли с помощью Service Worker перехватить http запрос и изменить его тело или заголовки.
  • Вопрос задан
  • 118 просмотров
Решения вопроса 1
bingo347
@bingo347
Бородатый программер
Одна из задач 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)); // если не наш случай, отправляем запрос на сервер,
    // тут так же можно заморочится с кэшем
  }
});


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

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

Войти через TM ID
Похожие вопросы