Ошибка регистрации Service Worker: неподдерживаемый тип MIME ('text / html')

Я использую создать-реагировать-приложение с сервером выражать.

create-react-app имеет предварительно настроенный ServiceWorker, который кэширует локальные активы (https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app).

Проблема, с которой я столкнулся при попытке публикации на своем сервере, заключается в том, что файл service-worker.js был доступен, но я получал ошибки в консоли браузера, когда он пытался его зарегистрировать.

В Firefox я получил эту ошибку:

Error during service worker registration:

TypeError: ServiceWorker script at https://my-domain.com/service-worker.js for scope https://my-domain.com/ encountered an error during installation.

В Chrome я получаю более описательную ошибку:

Error during service worker registration: DOMException: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html').

Разумеется, если я посмотрю на вкладку «Сеть» в своих инструментах разработчика и найду файл service-worker.js, я вижу, что в заголовках HTTP указан неправильный тип MIME.

Однако я не мог понять, почему у него неправильный тип MIME?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
43
0
60 613
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

Ответ принят как подходящий

В моем приложении Express-сервера у меня есть один маршрут с подстановочными знаками (звездочка / *), который перенаправляет на 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"));
  });
}

Это очень распространенный шаблон проектирования. Однако это означает, что любые запросы на неизвестные текстовые файлы изначально перенаправляются на index.html и, следовательно, возвращаются с MIME-типом "text/html", даже если это на самом деле JavaScript, SVG или какой-либо другой тип открытого текстового файла.

Решение, которое я нашел, заключалось в том, чтобы добавить конкретный маршрут для service-worker.jsперед подстановочный маршрут:

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

Теперь, когда браузер ищет service-worker.js, Express вернет его с правильным типом MIME.

(Обратите внимание, что если вы попытаетесь добавить маршрут service-worker.js после подстановочного символа, это не сработает, потому что подстановочный маршрут будет переопределен.)

Пожалуйста, что я должен указать, если мой файл index.html находится в клиентской / общей папке, а не только в общей папке? Я пробую этот res.sendFile(path.resolve(__dirname, "client", "public", "service-worker.js"));, но он возвращает неверный код ответа HTTP (404) при загрузке скрипта.

Nevada Stone 18.03.2021 01:58

ServiceWorker поддерживает типы MIME: text / javascript, application / javascript и application / x-javascript. перейдите в файл вашего сервера и установите

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

Сценарий имеет неподдерживаемый MIME-тип ('text / html'). Не удалось загрузить ресурс: net :: ERR_INSECURE_RESPONSE (индекс): 1 Неперехваченный (в обещании) DOMException: не удалось зарегистрировать ServiceWorker: сценарий имеет неподдерживаемый тип MIME ('text / html').

Код для корневого файла template.js

export default ({ markup, css }) => {
  return `<!doctype html>
      <html lang = "en">
        <head>
          <meta charset = "utf-8">
          <meta name = "viewport" content = "width=device-width, initial-scale=1.0">
          <title>MERN Marketplace</title>
          <link rel = "stylesheet" href = "https://fonts.googleapis.com/css?family=Roboto:100,300,400">
          <link rel = "stylesheet" href = "https://fonts.googleapis.com/icon?family=Material+Icons">

          <style>
              a{
                text-decoration: none
              }
          </style>
          <link rel = "manifest" href = "./manifest.json">
        </head>
        <body style = "margin:0">
            <div id = "root">${markup}</div>
          <style id = "jss-server-side">${css}</style>
          <script type = "text/javascript" src = "/dist/bundle.js"></script>
          <script>
          if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/sw.js').then(function() { 
              console.info("Service Worker Registered"); 
            });
          }
          </script>
        </body>
      </html>`;
};

Если это ответ, то какие первые 3 строки? И, пожалуйста, добавьте дополнительные пояснения к своему ответу

Mastisa 11.09.2018 07:00

Замена:

'/service-worker.js'

с участием:

'./service-worker.js'  // Add a dot before slash.

решил мою аналогичную проблему.

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

Это правильный ответ. Ошибка типа MIME является результатом того, что файл не найден.

Peter 26.07.2020 10:28

Реагировать: общедоступный / index.html

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

Примечание: полное приложение / сайт общедоступный / 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))
  );
});

При чем здесь React?

Spock 07.06.2019 08:28

Работаем без подключения

Oscar Corona 24.08.2019 23:52

Убедитесь, что файл служебного исполнителя создан (Chrome DevTools -> Источники -> Файловая система). Вы можете получить такую ​​ошибку, если файл сервис-воркера вообще не сгенерирован (проверьте свой сценарий развертывания).

Спасибо. Это была моя проблема. Похоже, что загрузочный шаблон / шаблон изменился с момента написания учебника. Возможно, там был файл serviceWorker.js - но он был в /src/, а не в /public/.

Morvael 10.03.2020 11:36

В случае, если вы работаете над NodeJS, файл serviceWorker следует разместить в общей папке. Если вы используете Webpack для экспорта serviceWorker в публичный доступ, вам необходимо использовать copy-webpack-plugin.

Я использую nginx для обслуживания приложения реагирования, и я решил эту проблему, добавив типы mime в nginx:

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

    # another config details
}

Также вы можете найти файл mime.types здесь

Я столкнулся с той же проблемой, и удаление других библиотек firebase из моей конфигурации решило проблему для меня Проверьте это на Github


// Change this 
var firebaseConfig = {
    apiKey: "*********",
    authDomain: "**********",
    databaseURL: "*********",
    projectId: "***********",
    storageBucket: "************",
    messagingSenderId: "***********",
    appId: "************"
};

// To =>
var firebaseConfig = {
  apiKey: "*****************",
  projectId: "**********",
  messagingSenderId: "*******",
  appId: "***********"
};

Я думаю, что файл сервисного работника отсутствует на http://localhost:3000/service-worker.js, поэтому сервер вместо этого возвращает index.html. Тогда функция регистрации не знает, что делать с файлом index.html, и сообщает вам, что тип MIME неверен.

Быстрое решение - скопировать файл service-worker.js в папку public, чтобы при нажатии http://localhost:3000/service-worker.js вы видели файл в браузере.

Не забудьте перейти в ChromeDev> Приложения> ServiceWorkers и нажать Отказаться от подписки. чтобы удалить ошибочный. Не забудьте также отключить кеш

Если вы не можете получить доступ к своему /public/service-worker.js. Поскольку он отчасти всегда отображает index.html, обязательно проверьте конфигурацию вашего виртуального хоста, если она у вас есть. Мои коллеги добавили правила, которые делали невозможным обслуживание файла SW.js из-за правил перенаправления.

Rémy Machado 29.01.2021 16:51

В моем случае для Vue мне нужно было сгенерировать mockServiceWorker.js в общедоступном каталоге с помощью инструмента командной строки, как описано здесь:

https://mswjs.io/docs/getting-started/integrate/browser

Мне это не было ясно из образцов. В частности, команда CLI для запуска:

npx msw init ./public
self.addEventListener('fetch', function(event) {});

Добавьте код выше в файл service-worker.js

Добро пожаловать в SO! Обратите внимание, что вы только что ответили на старый вопрос. Обычно мы отвечаем на этот вопрос, если в соответствующей версии программного обеспечения произошло какое-либо изменение, которое привело к устареванию синтаксиса принятого ответа. Если ваш ответ не добавляет новой информации, рассмотрите возможность его удаления.

My Koryto 22.09.2020 12:55

При запуске сервера webpack dev он отображает index.html по умолчанию для отсутствующего ресурса.

Если вы используете свой браузер для загрузки http://localhost:3000/sw.js, вы фактически увидите обработанное приложение реакции (запускаемое index.html). Вот почему тип пантомимы - это html, а не javascript.

Этот резервный вариант index.html разработан для поддержки СПА с интерфейсными маршрутами. Например, /product/123/reviews не имеет такого html-файла в бэкэнде, приложение JS SPA позаботится об этом во внешнем интерфейсе.

Почему ваш файл отсутствует? Я предполагаю, что вы создали этот файл в корневой папке вашего проекта.

Сервер разработки Webpack не обслуживается из этой корневой папки.

Переместите свой sw.js в папку public / вашего проекта, он будет обслуживаться, как ожидалось.

Я предполагаю, что файл служебного исполнителя должен находиться по корневому пути. В моем случае я не могу использовать корневой путь, поэтому перенаправляю service-worker.js на свой дополнительный путь, используя правило перенаправления apache.

 RewriteRule "^/service-worker.js$"  "/sub/service-worker.js"

У меня была аналогичная проблема при размещении сайта на Python. Ни одно из решений здесь не помогло мне, и я наткнулся на ошибка опубликована на форуме chrome dev, который помог решить мою проблему. По-видимому, в моем случае это была проблема, связанная с Windows, поскольку в записи реестра для файлов .js был установлен тип содержимого text / plain из-за некоторой предыдущей конфигурации, которую мне пришлось изменить обратно на application / javascript.

TL; DR:

  1. Открыть редактор реестра
  2. Перейдите в Computer \ HKEY_CLASSES_ROOT \ .js
  3. Измените тип содержимого на приложение / javascript
  4. Перезагрузите Chrome и запустите свой сайт

Надеюсь, это поможет кому-то, если ничего из вышеперечисленного не работает.

Другие вопросы по теме