Ответом является как мягкое «нет», так и возможное «да».
Когда фрагмент кода работает в другом контексте (например, веб-работник или iframe), у вас нет прямого контроляглобального объекта (1).
Более того, XMLHttpRequest - не единственный способ отправки сетевых запросов - у вас есть несколько других методов, главным из которых является fetch
api .
Тем не менее, в блоке есть относительно новый ребенок под названием «Рабочие службы», который может вам немало помочь!
Служащие службы
Служащие службы (Аббревиатуры SW) очень похожи на тех веб-работников, которых вы уже знаете, но вместо того, чтобы работать только на текущей странице, они продолжают работать в фоновом режиме, пока ваш пользователь остается в вашем домене.Они также глобальны для всего вашего домена , поэтому любые запросы, сделанные с вашего сайта, будут проходить через них.
Их основная цель в жизни - реагирование на сетевые запросы, обычно используемые для целей кэширования.и автономный контент, обслуживание push-уведомлений и несколько других нишевых применений.
Давайте рассмотрим небольшой пример (обратите внимание, запустите их с локального веб-сервера):
// index.html
<script>
navigator.serviceWorker.register('sw.js')
.then(console.log.bind(console, 'SW registered!'))
.catch(console.error.bind(console, 'Oh nose!'));
setInterval(() => {
fetch('/hello/');
}, 5000);
</script>
// sw.js
console.log('Hello from a friendly service worker');
addEventListener('fetch', event => {
console.log('fetch!', event);
})
Здесь мы регистрируемсяработник службы, а затем запрашивает страницу каждые 5 секунд.В сервисном работнике мы просто регистрируем каждое сетевое событие, которое может быть зафиксировано в событии fetch
.
При первой загрузке вы должны увидеть, что сервисный работник зарегистрирован.SW только начинают перехватывать запросы с первой страницы после того, как они были установлены ... поэтому обновите страницу, чтобы начать видеть события fetch
, регистрируемые в журнале.Я советую вам поэкспериментировать со свойствами события, прежде чем читать дальше, чтобы все было яснее.
Круто!Из возни с событием в консоли видно, что event.request
- это объект Request
, созданный нашим браузером.В идеальном мире мы могли бы получить доступ к event.request.headers
и добавить наши собственные заголовки!Мечтательно, не правда ли??
К сожалению, заголовки запроса / ответа защищены и неизменны .К счастью, мы упрямая группа и можем просто пересоздать запрос:
// sw.js
console.log('Hello from a friendly service worker');
addEventListener('fetch', event => {
console.log('fetch!', event);
// extract our request
const { request } = event;
// clone the current headers
const newHeaders = new Headers();
for (const [key, val] of request.headers) {
newHeaders.append(key, val);
}
// ...and add one of our own
newHeaders.append('Say-What', 'You heard me!');
// clone the request, but override the headers with our own
const superDuperReq = new Request(request, {
headers: newHeaders
});
// now instead of the original request, our new request will take precedence!
return fetch(superDuperReq);
});
Это несколько разных концепций в игре, так что все в порядке, если требуется несколько раз, чтобы получить.По сути, мы создаем новый запрос, который будет отправлен вместо исходного, и устанавливаем новый заголовок!Ура!
Плохое
Теперь о некоторых недостатках:
- Так как мыПерехищая каждый запрос , мы можем случайно изменить запросы, которые мы не собирались, и потенциально уничтожить всю вселенную!
- Обновление ПО - огромная боль.Жизненный цикл ПО сложен, отладка его для ваших пользователей затруднительна.Я видел хорошее видео о том, как справиться с этим, но, к сожалению, не могу найти его прямо сейчас, но mdn имеет довольно хорошее описание
- Отладка SW часто очень раздражает, особеннов сочетании с их странными жизненными циклами
- Поскольку они настолько мощные, СР могут обслуживаться только через https.Вы уже должны использовать https в любом случае, но это все еще является помехой
- Это много вещей, которые нужно сделать для сравнительно небольшого преимущества, поэтому, возможно, пересмотреть его необходимость
(1) Вы можете получить доступ к глобальному объекту iframe в того же источника , что и у вас, но получить код для запуска first для изменения глобального объекта действительно сложно.