web-dev-qa-db-ja.com

Service Workerの登録エラー:サポートされていないMIMEタイプ( 'text / html')

create-react-appexpress サーバーで使用しています。

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では、次のエラーが表示されました。

Service Workerの登録中のエラー:

TypeError:ServiceWorker script at https://my-domain.com/service-worker.js for scope https://my-domain.com/ でエラーが発生しましたインストール。

Chromeでは、よりわかりやすいエラーが表示されます。

Service Workerの登録中のエラー:DOMException:ServiceWorkerの登録に失敗しました:スクリプトにサポートされていないMIMEタイプ( 'text/html')があります。

案の定、開発者ツールの[ネットワーク]タブを見て、service-worker.jsファイル、HTTPヘッダーに間違ったMIMEタイプがあることがわかります。

しかし、なぜMIMEタイプが間違っているのか理解できませんでしたか?

11
MattSidor

Expressサーバーアプリケーションには、index.htmlにリダイレクトする1つのワイルドカード(アスタリスク/ *)ルートがあります。

// 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にリダイレクトされるため、実際にはJavaScriptまたはSVGまたは他の種類のプレーンテキストファイルであっても"text/html"のMIMEタイプで返されます。 。

私が見つけた解決策は、service-worker.jsに特定のルートを追加することでしたbeforeワイルドカードルート:

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ルートを追加しようとすると、ワイルドカードルートが上書きされるため機能しません。)

11
MattSidor

ServiceWorkerがサポートするMIMEタイプは、「text/javascript」、application/javascript、およびapplication/x-javascriptです。 urサーバーファイルにアクセスして設定

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

交換

_'/service-worker.js'
_

_'./service-worker.js'
_

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

同様の問題を解決しました。

3
Mir-Ismaili

Service Workerファイルが生成されていることを確認します(Chrome DevTools-> Sources-> Filesystem)。 Service Workerファイルがまったく生成されない場合は、このようなエラーが表示される場合があります(展開スクリプトを確認してください)。

1

反応: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))
  );
});
1
Oscar Barrios

NodeJSで作業している場合、serviceWorkerファイルはパブリックフォルダーに配置する必要があります。 Webpackを使用してserviceWorkerをパブリックにエクスポートする場合は、「copy-webpack-plugin」を使用する必要があります。

1
Hoang Duong

このスクリプトには、サポートされていない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>`;
};