我将create-react-app与express服务器一起使用。
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:范围https://my-domain.com/service-worker.js https://my-domain.com/的ServiceWorker脚本在安装过程中遇到错误。
在Chrome上,我收到了更具描述性的错误:
服务工作者注册期间出错:DOMException:无法注册ServiceWorker:脚本的MIME类型不受支持(' text / html')。
果然,如果我查看开发人员工具的“网络”选项卡并搜索service-worker.js
文件,我可以看到HTTP标头中的MIME类型错误。
我无法理解为什么它的MIME类型错误?
答案 0 :(得分:7)
在我的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
路由,它将无法正常工作,因为通配符路由将覆盖。)
答案 1 :(得分:7)
我认为if (!String.prototype.replaceAll)
{
String.prototype.replaceAll = function(search, replace){
return this.split(search).join(replace);
}
}
中不存在服务工作者文件,因此服务器将返回index.html。然后,注册功能不知道如何处理index.html文件,并告诉您MIME类型不正确。
一种快速的解决方法是将service-worker.js文件复制到n = 4 # for reading from 5th line
with open("write.txt",'r') as t:
for i,line in enumerate(t):
if i >= n: # i == n-1 for nth line
print(line)
文件夹中,这样,当您点击Select * from table where id in (select distincnt(id) from table );
时,便会在浏览器中看到该文件。
请记住,请转到ChromeDev>应用程序> ServiceWorkers,然后点击取消订阅。为了删除错误的。记住还要禁用缓存
答案 2 :(得分:2)
ServiceWorker支持的MIME类型是“文本/ javascript”,应用程序/ javascript和应用程序/ x-javascript。进入您的服务器文件并设置
response.writeHead(201, {
'Content-Type': 'application/javascript'
});
答案 3 :(得分:2)
替换
'/service-worker.js'
使用
'./service-worker.js'
(在navigator.serviceWorker.register('/service-worker.js')
中)
解决了我的类似问题。
答案 4 :(得分:1)
确保已生成服务辅助文件(Chrome DevTools->源->文件系统)。如果根本没有生成服务工作者文件,则可能会收到此类错误(请检查您的部署脚本)。
答案 5 :(得分:1)
如果您正在使用NodeJS,则serviceWorker文件应放在公共文件夹中。 如果您使用Webpack将serviceWorker导出到公共场所,则需要使用“ copy-webpack-plugin”。
答案 6 :(得分:1)
我使用nginx来服务react app,我解决了向nginx添加mime类型的问题:
http {
include mime.types; // <--- this line
# another config details
}
您还可以找到mime.types file here
答案 7 :(得分:1)
就我而言,对于Vue,我需要使用如下所述的命令行工具在公共目录中生成mockServiceWorker.js:
https://mswjs.io/docs/getting-started/integrate/browser
从我的样品中还不清楚。具体来说,要运行的CLI命令是:
npx msw init ./public
答案 8 :(得分:0)
反应: 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))
);
});
答案 9 :(得分:0)
我遇到了同样的问题,并且从配置中删除了其他firebase库,对我来说Check this on Github
// Change this
var firebaseConfig = {
apiKey: "*********",
authDomain: "**********",
databaseURL: "*********",
projectId: "***********",
storageBucket: "************",
messagingSenderId: "***********",
appId: "************"
};
// To =>
var firebaseConfig = {
apiKey: "*****************",
projectId: "**********",
messagingSenderId: "*******",
appId: "***********"
};
答案 10 :(得分:0)
运行 webpack 开发服务器时,它会为缺少的资源呈现默认的 index.html。
如果您使用浏览器加载 http://localhost:3000/sw.js
,您实际上会看到一个渲染的 React 应用程序(由 index.html 启动)。这就是为什么 mime 类型是 html,而不是 javascript。
这种对 index.html 的回退旨在通过前端路由支持 SPA。例如 /product/123/reviews
在后端没有这样的 html 文件,JS SPA 应用程序会在前端处理它。
为什么你的文件丢失了?我猜您在项目的根文件夹中创建了该文件。
Webpack 开发服务器不从该根文件夹提供服务。
答案 11 :(得分:0)
我猜,Service Worker 文件应该在根路径上。就我而言,我不能使用根路径,所以我使用 apache 重定向规则将 service-worker.js 重定向到我的子路径。
RewriteRule "^/service-worker.js$" "/sub/service-worker.js"
答案 12 :(得分:0)
我在用 python 托管网站时遇到了类似的问题。这里的任何解决方案都不适合我,我遇到了一个 bug posted in chrome dev forum,它设法解决了我的问题。显然,在我的情况下,这是与 Windows 相关的问题,因为 .js 文件的注册表项将内容类型设置为 text/plain 由于某些先前的配置,我不得不改回 application/javascript。
TLDR:
希望这对某些人有所帮助,以防上述方法均无效。
答案 13 :(得分:-1)
该脚本具有不受支持的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.log("Service Worker Registered");
});
}
</script>
</body>
</html>`;
};
答案 14 :(得分:-1)
self.addEventListener('fetch', function(event) {});
在您的service-worker.js文件中添加上述代码