Service Worker: anexar cabeçalho às solicitações de arquivos CSS e JS

8

Eu tenho tentado usar trabalhadores de serviço por (o que parece horas e horas), para anexar um cabeçalho simples a todas as solicitações. O que é frustrante é que funciona.

Tentativa 1:

self.addEventListener("fetch", event => {
   const modifiedHeaders = new Headers({
      ...event.request.headers,
      'API-Key': '000000000000000000001'
   });
   const modifiedRequest = new Request(event.request, {
      headers: modifiedHeaders,
   }); 
   event.respondWith((async () => {
     return fetch(modifiedRequest);
   })());
});

O código acima funciona para arquivos HTML, no entanto, para arquivos CSS e JS, recebo o seguinte erro

ReferenceError: headers não está definido

Se eu desativar o requisito do cabeçalho, a página carrega imagens e javascript e posso interagir com ele normalmente.

Tentativa 2:

var req = new Request(event.request.url, {
   headers: {
     ...event.request.headers,
      'API-Key': '000000000000000000001'
      },
   method: event.request.method,
   mode:  event.request.mode,
   credentials: event.request.credentials,
   redirect: event.request.redirect,
   referrer: event.request.referrer,
   referrerPolicy: event.request.referrerPolicy,
   bodyUsed: event.request.bodyUsed,
   cache: event.request.cache,
   destination: event.request.destination,
   integrity: event.request.integrity,
   isHistoryNavigation: event.request.isHistoryNavigation,
   keepalive:  event.request.keepalive
 });

Nesta tentativa, simplesmente criei uma nova solicitação, que incluiu com êxito o novo cabeçalho nas solicitações de arquivos CSS e JS. No entanto, quando eu faço um POST ou redireciono, as coisas param de funcionar e se comportam de forma estranha.

Qual é a abordagem correta para isso? Sinto que a tentativa 1 é o melhor caminho, mas não consigo criar o objeto Headers na solicitação, não importa o que eu faça.

A versão do chrome que estou usando é

Versão 78.0.3904.70 (versão oficial) (64 bits)

O site é uma ferramenta interna para desenvolvedores, portanto, a compatibilidade entre navegadores não é necessária. Por isso, estou feliz em carregar quaisquer bibliotecas adicionais / ativar recursos experimentais etc.

Jamie
fonte
3
Oi Jamie, você passou por este stackoverflow.com/questions/35420980/… ?
Manoj Kumar

Respostas:

1

O problema é que suas solicitações modificadas reutilizam a modesolicitação original nas duas tentativas

Para recursos incorporados nos quais a solicitação é iniciada a partir da marcação (a menos que o atributo crossorigin esteja presente), na maioria dos casos, a solicitação é feita usando o no-corsmodo que permite apenas um conjunto específico muito limitado de cabeçalhos simples .

no-cors - Impede que o método não seja HEAD, GET ou POST, e os cabeçalhos não sejam simples cabeçalhos. Se algum ServiceWorkers interceptar essas solicitações, ele não poderá adicionar ou substituir nenhum cabeçalho, exceto aqueles que são simples.

Fonte e mais informações sobre os modos de solicitação: https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Cabeçalhos simples são os seguintes: accept(apenas alguns valores), accept-language, content-language(apenas alguns valores), content-type.

Fonte: https://fetch.spec.whatwg.org/#simple-header :

Solução:

Você precisa definir o modo para algo diferente de no-corsquando criar a solicitação modificada. Você pode escolher um corsou same-origin, dependendo se deseja permitir solicitações de origem cruzada. (O navigatemodo está reservado apenas para navegação e não é possível criar uma solicitação com esse modo.)

Por que seu código funcionou para arquivos HTML:

A solicitação emitida ao navegar para uma nova página usa o navigatemodo O Chrome não permite criar solicitações com esse modo usando o new Request()construtor, mas parece usar automaticamente o same-originmodo silenciosamente quando uma solicitação existente com o navigatemodo é passada ao construtor como parâmetro. Isso significa que sua primeira solicitação modificada (carregamento HTML) teve o same-originmodo, enquanto as solicitações de carregamento CSS e JS tiveram o no-corsmodo.


Exemplo de trabalho:

'use strict';

/* Auxiliary function to log info about requests to the console */
function logRequest(message, req) {
  const headersString = [...req.headers].reduce((outputString, val) => `${outputString}\n${val[0]}: ${val[1]}`, 'Headers:');
  console.log(`${message}\nRequest: ${req.url}\nMode: ${req.mode}\n${headersString}\n\n`);
}


self.addEventListener('fetch', (event) => {
  logRequest('Fetch event detected', event.request);

  const modifiedHeaders = new Headers(event.request.headers);
  modifiedHeaders.append('API-Key', '000000000000000000001');

  const modifiedRequestInit = { headers: modifiedHeaders, mode: 'same-origin' };
  const modifiedRequest = new Request(event.request, modifiedRequestInit);

  logRequest('Modified request', modifiedRequest);

  event.respondWith((async () => fetch(modifiedRequest))());
});
Petr Srníček
fonte
-2

Eu tentaria o seguinte:

self.addEventListener("fetch", event => {
    const modifiedRequest = new Request(event.request, {
        headers: {
            'API-Key': '000000000000000000001'
        },
    }); 
    event.respondWith((async () => {
        return fetch(modifiedRequest);
    })());
});
Stefan Ziegler
fonte
1
Eu não teria mais meus cabeçalhos originais, em vez de anexar minha chave de API. Esta resposta não é útil.
Jamie
Ainda não tentei, mas a documentação diz que os cabeçalhos foram adicionados à solicitação. Você já tentou isso? Ele substitui os cabeçalhos da solicitação original ou essa chamada do construtor usa os cabeçalhos da solicitação anterior e adiciona os novos cabeçalhos? A única razão pela qual você vê erros é um problema com os cabeçalhos. Você já verificou os cabeçalhos da solicitação final (modifiedRequest)?
Stefan Ziegler