Ошибка регистрации Service Worker: неподдерживаемый тип MIME ('text/html')
Я использую create-реагировать-приложение с экспресс-сервером.
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 я получил эту ошибку:
Ошибка при регистрации сервисного работника:
TypeError: ServiceWorker script at https://my-domain.com/service-worker.js for scope https://my-domain.com/ encountered an error during installation.
В Chrome я получаю более описательную ошибку:
Ошибка при регистрации работника службы: DOMException: не удалось зарегистрировать ServiceWorker: сценарий имеет неподдерживаемый тип MIME ('text/html').
Конечно, если я загляну на вкладку "Сеть" моих инструментов разработчика и найду файл service-worker.js
, то увижу, что в заголовках HTTP указан неправильный тип MIME.
Я не мог понять, однако, почему он имеет неправильный тип MIME?
Ответы
Ответ 1
В моем приложении Express Server у меня есть один шаблон (звездочка/*), который перенаправляется на 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
после шаблона, это не сработает, потому что маршрут подстановочного знака будет отменен.)
Ответ 2
ServiceWorker поддерживает MIME-тип: "text/javascript", application/javascript и application/x-javascript. добрался до файла сервера ur и установил
response.writeHead(201, {
'Content-Type': 'application/javascript'
});
Ответ 3
Замена
'/service-worker.js'
с
'./service-worker.js'
(в navigator.serviceWorker.register('/service-worker.js')
)
решил мою похожую проблему.
Ответ 4
Реагируйте: public/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>
Примечание: полное приложение/сайт public/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))
);
});
Ответ 5
Убедитесь, что рабочий файл сервиса создан (Chrome DevTools → Sources → Filesystem). Вы можете получить такую ошибку, если файл рабочего сервиса не сгенерирован вообще (проверьте скрипт развертывания).
Ответ 6
В случае, если вы работаете с NodeJS, файл serviceWorker должен находиться в общей папке.
Если вы используете Webpack для экспорта serviceWorker в открытый доступ, вам нужно использовать "copy-webpack-plugin".
Ответ 7
Сценарий имеет неподдерживаемый тип 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="#" onclick="location.href='https://fonts.googleapis.com/css?family=Roboto:100,300,400'; return false;">
<link rel="stylesheet" href="#" onclick="location.href='https://fonts.googleapis.com/icon?family=Material+Icons'; return false;">
<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.log("Service Worker Registered");
});
}
</script>
</body>
</html>';
};