Я использую создать-реагировать-приложение с сервером выражать.
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?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В моем приложении 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 после подстановочного символа, это не сработает, потому что подстановочный маршрут будет переопределен.)
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 строки? И, пожалуйста, добавьте дополнительные пояснения к своему ответу
Замена:
'/service-worker.js'
с участием:
'./service-worker.js' // Add a dot before slash.
решил мою аналогичную проблему.
(in navigator.serviceWorker.register('/service-worker.js'))
Это правильный ответ. Ошибка типа MIME является результатом того, что файл не найден.
Реагировать: общедоступный / 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?
Работаем без подключения
Убедитесь, что файл служебного исполнителя создан (Chrome DevTools -> Источники -> Файловая система). Вы можете получить такую ошибку, если файл сервис-воркера вообще не сгенерирован (проверьте свой сценарий развертывания).
Спасибо. Это была моя проблема. Похоже, что загрузочный шаблон / шаблон изменился с момента написания учебника. Возможно, там был файл serviceWorker.js - но он был в /src/, а не в /public/.
В случае, если вы работаете над 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 из-за правил перенаправления.
В моем случае для 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! Обратите внимание, что вы только что ответили на старый вопрос. Обычно мы отвечаем на этот вопрос, если в соответствующей версии программного обеспечения произошло какое-либо изменение, которое привело к устареванию синтаксиса принятого ответа. Если ваш ответ не добавляет новой информации, рассмотрите возможность его удаления.
При запуске сервера webpack dev он отображает index.html по умолчанию для отсутствующего ресурса.
Если вы используете свой браузер для загрузки http://localhost:3000/sw.js, вы фактически увидите обработанное приложение реакции (запускаемое index.html). Вот почему тип пантомимы - это html, а не javascript.
Этот резервный вариант index.html разработан для поддержки СПА с интерфейсными маршрутами. Например, /product/123/reviews не имеет такого html-файла в бэкэнде, приложение JS SPA позаботится об этом во внешнем интерфейсе.
Почему ваш файл отсутствует? Я предполагаю, что вы создали этот файл в корневой папке вашего проекта.
Сервер разработки Webpack не обслуживается из этой корневой папки.
Я предполагаю, что файл служебного исполнителя должен находиться по корневому пути. В моем случае я не могу использовать корневой путь, поэтому перенаправляю service-worker.js на свой дополнительный путь, используя правило перенаправления apache.
RewriteRule "^/service-worker.js$" "/sub/service-worker.js"
У меня была аналогичная проблема при размещении сайта на Python. Ни одно из решений здесь не помогло мне, и я наткнулся на ошибка опубликована на форуме chrome dev, который помог решить мою проблему. По-видимому, в моем случае это была проблема, связанная с Windows, поскольку в записи реестра для файлов .js был установлен тип содержимого text / plain из-за некоторой предыдущей конфигурации, которую мне пришлось изменить обратно на application / javascript.
TL; DR:
Надеюсь, это поможет кому-то, если ничего из вышеперечисленного не работает.
Пожалуйста, что я должен указать, если мой файл
index.htmlнаходится в клиентской / общей папке, а не только в общей папке? Я пробую этотres.sendFile(path.resolve(__dirname, "client", "public", "service-worker.js"));, но он возвращает неверный код ответа HTTP (404) при загрузке скрипта.