Javascript 服务工作人员注册错误:不支持的MIME类型(';text/html';)

Javascript 服务工作人员注册错误:不支持的MIME类型(';text/html';),javascript,reactjs,express,service-worker,create-react-app,Javascript,Reactjs,Express,Service Worker,Create React App,我正在使用服务器 create react app有一个预配置的ServiceWorker,用于缓存本地资产() 当我尝试在服务器上发布时遇到的问题是,service worker.js文件可用,但我的浏览器控制台在尝试注册时出错 在Firefox上,我遇到了以下错误: 服务人员注册期间出错: TypeError:for作用域的ServiceWorker脚本在安装过程中遇到错误 在Chrome上,我得到了更具描述性的错误: 服务工作者注册期间出错:DomeException:注册服务工作者失败:

我正在使用服务器

create react app
有一个预配置的ServiceWorker,用于缓存本地资产()

当我尝试在服务器上发布时遇到的问题是,
service worker.js
文件可用,但我的浏览器控制台在尝试注册时出错

在Firefox上,我遇到了以下错误:

服务人员注册期间出错:

TypeError:for作用域的ServiceWorker脚本在安装过程中遇到错误

在Chrome上,我得到了更具描述性的错误:

服务工作者注册期间出错:DomeException:注册服务工作者失败:脚本具有不受支持的MIME类型(“text/html”)

果不其然,如果我查看开发人员工具的“网络”选项卡并搜索
service worker.js
文件,我可以看到它在HTTP头中的MIME类型是错误的


不过,我不明白为什么它的MIME类型不正确?

在我的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
路由,它将不起作用,因为通配符路由将覆盖。)

ServiceWorker支持的MIME类型是“text/javascript”、application/javascript和application/x-javascript。转到服务器文件并设置

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

该脚本具有不受支持的MIME类型(“text/html”)。 未能加载资源:net::错误\u不安全\u响应 (索引):1未捕获(承诺中)DOMEException:注册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>`;
};
导出默认值({markup,css})=>{
返回`
梅恩市场
a{
文本装饰:无
}
${markup}
${css}
if(导航器中的“serviceWorker”){
register('/sw.js')。然后(function(){
console.log(“服务人员注册”);
});
}
`;
};
更换:

'/service-worker.js'
与:

解决了我类似的问题

(在
navigator.serviceworner.register('/service worker.js')
)中)反应: 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>

确保生成了服务工作者文件(chromedevtools->Sources->Filesystem)。如果根本没有生成service worker文件,您可能会收到此类错误(请检查您的部署脚本)。

如果您使用的是NodeJ,则serviceWorker文件应放在公用文件夹中。
如果您使用Webpack将serviceWorker导出到公共,则需要使用“复制Webpack插件”。

我使用nginx为react应用程序提供服务,并通过向nginx添加mime类型解决了此问题:

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

    # another config details
}
http{

include mime.types;//我也面临同样的问题,从配置中删除其他firebase库可以帮我解决这个问题


//改变这个
var firebaseConfig={
apiKey:“**********”,
authDomain:“**********”,
数据库URL:“**********”,
项目D:“**********”,
storageBucket:“*************”,
messagingSenderId:“**********”,
appId:“*************”
};
//至=>
var firebaseConfig={
apiKey:“****************”,
项目D:“**********”,
messagingSenderId:“*******”,
appId:“*************”
};

我认为服务人员文件在
http://localhost:3000/service-worker.js
因此服务器返回index.html。然后注册函数不知道如何处理index.html文件,并告诉您MIME类型不正确

一个快速修复方法是将service-worker.js文件复制到
public
文件夹中,这样当您点击
http://localhost:3000/service-js
您可以在浏览器中看到该文件


请记住转到ChromeDev>Applications>ServiceWorkers并点击Unsubscribe。为了删除错误的一个。还请记住禁用缓存在我的情况下,对于Vue,我需要使用命令行工具在公用目录中生成mockServiceWorker.js,如下所述:

我从示例中不清楚这一点。具体来说,要运行的CLI命令是:

npx msw init ./public

在service-worker.js文件中添加上述代码

运行webpack dev server时,它会为缺少的资源呈现默认index.html

如果使用浏览器加载
http://localhost:3000/sw.js
,您将实际看到一个呈现的react应用程序(由index.html启动)。这就是mime类型是html而不是javascript的原因

此index.html回退旨在支持前端路由的SPA。例如,
/product/123/reviews
后端没有此类html文件,JS SPA应用程序在前端处理

为什么文件丢失?我想是您在项目的根文件夹中创建了该文件

网页包开发服务器不从该根文件夹提供服务。


将您的sw.js移动到项目的public/文件夹中,它将按预期提供。我想,服务工作者文件应该位于根路径上。在我的情况下,我无法使用根路径,因此我重定向服务工作者文件
http {
    include    mime.types; // <--- this line

    # another config details
}
npx msw init ./public
self.addEventListener('fetch', function(event) {});
 RewriteRule "^/service-worker.js$"  "/sub/service-worker.js"