Service Worker: agregue encabezado a las solicitudes de archivos CSS y JS

8

He estado tratando de usar trabajadores de servicio para (lo que parecen horas y horas), para adjuntar un encabezado simple a todas las solicitudes. Lo que es frustrante es que funciona.

Intento 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);
   })());
});

El código anterior funciona para archivos HTML, sin embargo, para los archivos CSS y JS recibo el siguiente error

ReferenceError: los encabezados no están definidos

Si desactivo el requisito de encabezado, la página se carga con imágenes y JavaScript y puedo interactuar con él como de costumbre.

Intento 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
 });

Este intento, simplemente construí una nueva solicitud, que incluyó con éxito el nuevo encabezado en las solicitudes de archivos CSS y JS. Sin embargo, cuando hago una POST o redirecciono, las cosas dejan de funcionar y se comportan de manera extraña.

¿Cuál es el enfoque correcto para esto? Siento que el intento 1 es el mejor camino, pero parece que no puedo crear el objeto Headers en la solicitud sin importar lo que haga.

La versión de Chrome que estoy usando es

Versión 78.0.3904.70 (compilación oficial) (64 bits)

El sitio es una herramienta interna para desarrolladores, por lo que no se requiere compatibilidad cruzada con el navegador. Así que estoy feliz de cargar cualquier libs adicional / habilitar funciones experimentales, etc.

Jamie
fuente
3
Hola Jamie, ¿ pasaste por este stackoverflow.com/questions/35420980/… ?
Manoj Kumar el

Respuestas:

1

El problema es que sus solicitudes modificadas reutilizan las modede la solicitud original en ambos intentos

Para los recursos integrados donde la solicitud se inicia desde el marcado (a menos que esté presente el atributo crossorigin), la solicitud se realiza en la mayoría de los casos utilizando el no-corsmodo que solo permite un conjunto específico muy limitado de encabezados simples .

no-cors: evita que el método no sea HEAD, GET o POST, y que los encabezados sean algo más que simples encabezados. Si algunos ServiceWorkers interceptan estas solicitudes, no pueden agregar ni anular ningún encabezado, excepto aquellos que son encabezados simples ...

Fuente y más información sobre los modos de solicitud: https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Los encabezados simples son los siguientes: accept (a sólo algunos valores), accept-language, content-language(sólo algunos valores), content-type.

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

Solución:

Debe asegurarse de establecer el modo en algo diferente no-corsal crear la solicitud modificada. Puedes elegir cualquiera corsosame-origin , dependiendo de si desea permitir solicitudes de origen cruzado. (El navigatemodo está reservado solo para navegación y no es posible crear una solicitud con ese modo).

Por qué su código funcionó para archivos HTML:

La solicitud emitida al navegar a una nueva página utiliza el navigatemodo. Chrome no permite crear solicitudes con este modo usando el new Request()constructor, pero parece usar automáticamente el same-originmodo silenciosamente cuando una solicitud existente con el navigatemodo se pasa al constructor como parámetro. Esto significa que su primera solicitud modificada (carga HTML) tenía same-originmodo, mientras que las solicitudes de carga CSS y JS tenían el no-corsmodo.


Ejemplo de trabajo:

'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
fuente
-2

Yo intentaría esto:

self.addEventListener("fetch", event => {
    const modifiedRequest = new Request(event.request, {
        headers: {
            'API-Key': '000000000000000000001'
        },
    }); 
    event.respondWith((async () => {
        return fetch(modifiedRequest);
    })());
});
Stefan Ziegler
fuente
1
Ya no tendría mis encabezados originales, en lugar de agregar mi clave API. Esta respuesta no es útil.
Jamie
No lo he intentado, pero la documentación dice que los encabezados se agregan a la solicitud. ¿Ya lo has probado? ¿Reemplaza los encabezados de la solicitud original o esta llamada de constructor usa los encabezados de la solicitud anterior y le agrega los nuevos encabezados? La única razón por la que ve errores es un problema con los encabezados. ¿Ya revisó los encabezados de la solicitud final (modifiedRequest)?
Stefan Ziegler