Error de registro de Service Worker: tipo MIME no admitido (‘text/html’)

5 minutos de lectura

Avatar de usuario de MattSidor
MattSidor

Estoy usando crear-reaccionar-app con un Rápido servidor.

create-react-app tiene un ServiceWorker preconfigurado que almacena en caché los activos locales (https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app).

El problema que encontré cuando traté de publicar en mi servidor es que el service-worker.js estaba disponible, pero recibía errores en la consola de mi navegador cuando intentaba registrarlo.

En Firefox, recibí este error:

Error durante el registro del trabajador del servicio:

TypeError: secuencia de comandos ServiceWorker en https://example.com/service-worker.js para alcance https://example.com/ encontró un error durante la instalación.

En Chrome, obtengo el error más descriptivo:

Error durante el registro del trabajador de servicio: DOMException: no se pudo registrar un trabajador de servicio: el script tiene un tipo MIME no compatible (‘texto/html’).

Efectivamente, si miro en la pestaña Red de mis herramientas de desarrollador y busco el service-worker.js archivo, puedo ver que tiene el tipo MIME incorrecto en los encabezados HTTP.

Sin embargo, no pude entender por qué tiene el tipo MIME incorrecto.

Avatar de usuario de Mir-Ismaili
Mir-Ismaili

Aplicando este cambio:

'/service-worker.js'  // ❌
'./service-worker.js' // ✅

solucionó mi problema.

(en navigator.serviceWorker.register('/service-worker.js'))


O tal vez necesites:

'%PUBLIC_URL%/serviceworker.js'

Gracias a @DanielLord por su comentario.

  • Esta es la respuesta correcta. El error de tipo MIME es el resultado de un archivo no encontrado.

    – Pedro

    26 de julio de 2020 a las 8:28

  • El mío tomó cambiarlo a “%PUBLIC_URL%/serviceworker.js”. Pero me hiciste darme cuenta de que era la ruta la que estaba mal, no el tipo MIME

    – Daniel Señor

    1 feb a las 22:41

En mi aplicación de servidor Express, tengo una ruta comodín (asterisco / *) que redirige a index.html:

// Load React App
// Serve HTML file for production
if (env.name === "production") {
  app.get("*", function response(req, res) {
    res.sendFile(path.join(__dirname, "public", "index.html"));
  });
}

Este es un patrón de diseño muy común. Sin embargo, significa que cualquier solicitud de archivos de texto desconocidos se redirige inicialmente a index.htmly por lo tanto volver con el tipo MIME de "text/html"incluso si en realidad es JavaScript o SVG o algún otro tipo de archivo de texto sin formato.

La solución que encontré fue agregar una ruta específica para service-worker.js antes de la ruta comodín:

app.get("/service-worker.js", (req, res) => {
  res.sendFile(path.resolve(__dirname, "public", "service-worker.js"));
});
app.get("*", function response(req, res) {
  res.sendFile(path.join(__dirname, "public", "index.html"));
});

Ahora, cuando el navegador busca service-worker.jsExpress lo devolverá con el tipo MIME correcto.

(Tenga en cuenta que si intenta agregar el service-worker.js ruta después del comodín, no funcionará porque la ruta comodín se anulará).

  • Por favor, ¿qué debo especificar si mi index.html el archivo está en la carpeta pública/cliente y no solo en una carpeta pública? intento esto res.sendFile(path.resolve(__dirname, "client", "public", "service-worker.js")); pero devuelve Se recibió un código de respuesta HTTP incorrecto (404) al obtener el script.

    – Piedra Nevada

    18 de marzo de 2021 a las 0:58


Creo que el archivo del trabajador del servicio no está presente en http://localhost:3000/service-worker.js por lo que el servidor está devolviendo index.html en su lugar. Luego, la función de registro no tiene idea de qué hacer con un archivo index.html y le dice que el tipo MIME no es correcto.

Una solución rápida sería copiar el archivo service-worker.js en el public carpeta para que cuando pulses http://localhost:3000/service-worker.js ves el archivo en el navegador.

Recuerde ir a ChromeDev > Aplicaciones > ServiceWorkers y presione Cancelar suscripción. para eliminar el erróneo. Recuerda también deshabilitar caché

  • Si no puede llegar a su /public/service-worker.js. Que de alguna manera siempre representa index.html, asegúrese de verificar su configuración de vhost si tiene una. Mis compañeros de trabajo agregaron reglas que hacían que el archivo SW.js fuera imposible de servir debido a las reglas de redirección.

    – Entrada de polarización

    29 de enero de 2021 a las 15:51

Avatar de usuario de WapShivam
wapshivam

Los tipos MIME compatibles con ServiceWorker son ‘text/javascript’, application/javascript y application/x-javascript. vaya a su archivo de servidor y configure

    response.writeHead(201, {
        'Content-Type': 'application/javascript'
    });

Uso nginx para servir la aplicación de reacción y resolví este problema agregando tipos mime a nginx:

http {
    include    mime.types; // <--- this line

    # another config details
}

También puedes encontrar archivo mime.types aquí

En caso de que esté trabajando en NodeJS, el archivo serviceWorker debe colocarse en la carpeta pública. Si está utilizando Webpack para exportar serviceWorker al público, debe usar ‘copy-webpack-plugin’.

Reaccionar: public/index.html

<script> 
  if ('serviceWorker' in navigator) {
    window.addEventListener('sw-cached-site.js', function() {
      navigator.serviceWorker.register('service-worker.js', {
        scope: "https://stackoverflow.com/",
      });
    });
  } 
  window.process = { env: { NODE_ENV: 'production' } };
</script>

Nota: aplicación completa/sitio público/sw-cached-site.js

const cacheName="v1";
self.addEventListener('activate', (e) =>{
  e.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cache => {
          if(cache !== cacheName) { 
            return caches.delete(cache);
          }
        })
      )
    })
  )
});
self.addEventListener('fetch', e => { 
  e.respondWith(
      fetch(e.request)
        .then(res => {
            const resClone = res.clone();
            caches
                .open(cacheName)
                .then(cache => {
                    cache.put(e.request, resClone);
                }); 
                return res;
        }).catch(err => caches.match(e.request).then(res => res))
  );
});

  • ¿Qué tiene esto que ver con React?

    – Spock

    7 de junio de 2019 a las 6:28

  • Trabajar sin conexión

    – Óscar Corona

    24 de agosto de 2019 a las 21:52

¿Ha sido útil esta solución?