web-dev-qa-db-ja.com

Angular 7-サーバーでService Worker PWA + SSRが機能しない

サーバー側のレンダリングとサービスワーカーをサーバー側で連携させるのに苦労しています。

localhostに関する情報->作業中

これは期待どおりに機能しています。 Service Workerは、更新のたびに私のアプリを動作させて更新します。さらに、 curl localhost:8082情報を送ってください。

次のコマンドでアプリを起動します:npm run ssr

 "ssr": "npm run build:ssr && npm run serve:ssr",
 "build:ssr": "npm run build:client-and-server-bundles",
 "serve:ssr": "node dist/server.js",
 "build:client-and-server-bundles": "ng build --prod && npm run webpack:server",
 "webpack:server": "webpack --config webpack.server.config.js --progress --colors"

生産に関する情報:->機能していません

ウェブサイトはHTTPS経由です: https://airdropers.io ウェブサイトプロセスはクローズポートで実行されており、トラフィックを443からウェブサーバーのポートにリダイレクトしています

Webサーバーログに表示される問題:通知をサブスクライブできませんでしたエラー:サービスワーカーが無効になっているか、このブラウザーでサポートされていません

追加情報:

Localhostと本番のノードjsは同じです:v9.0.0次のプロセスで本番環境に構築します。

  1. git pull
  2. npm run build:ssr
  3. pm2 start dist/server.js

更新23/02/2019

私は今より深く理解しています。私の問題は、「node dist/server.js」などのノードコマンドでSSR/PWAサーバーを起動することです。

私の理解から、 "node dist/server.js"はService Worker(PWA)で機能していません( https://angular.io/guide/service-worker-getting-started

Ng serveはService Workerでは機能しないため、プロジェクトをローカルでテストするには、別のHTTPサーバーを使用する必要があります。任意のHTTPサーバーを使用できます。以下の例では、npmのhttp-serverパッケージを使用しています。競合の可能性を減らし、古いコンテンツの提供を回避するには、専用ポートでテストし、キャッシュを無効にします。

起動できないのはhttp-server dist/browser SSR機能が失われるためです。

PWA/SSRサーバーを起動するにはどうすればよいですか?どのコマンドを使用しますか?
どのビルドを実行しますか?

更新24/02/2019

@GökhanKurtが述べたように、サービスワーカーが私のSSRサーバーで正しく動作していません。 SEOにはSSRが必要で、ブラウザープッシュ通知にはService Workerが必要です。ブラウザのユーザープッシュ通知を処理するには、どのようなソリューションが必要ですか? One Signalsなどのサードパーティのlib?


アイデアの提案は私がその仕事をするのを助けるために大歓迎です。アレックス、サポートありがとう

11
aorfevre

実際にはサーバーとはまったく関係ありません。問題は、Service Workerがサーバー側で登録されようとしていることです。これはサポートされていません。あなたができることは、Service Workerがクライアント側で登録できるようにすることです。

私は試していませんが、これはあなたのためにうまくいくかもしれません。ブラウザで実行するには、index.htmlbodyの最後に別のスクリプトを配置する必要があります。

  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/ngsw-worker.js');
    }
  </script>

これはService Workerの基本的なキャッシング機能のみを提供し、SwPushまたはSwUpdateでは機能しないことに注意してください。 Service Workerモジュールが内部でどのように動作するかを確認できます ここ

もう1つ知っておくべきことは、Service Workerは実際にはSSRアプリには適さないということです。生成されたngsw.jsonファイルには、すべてのページが含まれるわけではありません。このファイルを手動で変更するか、静的ファイルではなく動的に作成する必要があります。

そして、すべてのページをキャッシュすることは、あなたがやりたいことではありません(ページのコンテンツが静的でない限り)。クライアント側でXHRリクエストを行わないため、キャッシュされたページは常に同じものを表示するからです。たとえば、ホームページがクライアント用にキャッシュされている場合、そのクライアントには、目的の動的コンテンツに関係なく、常に同じページが表示されます。

この時点で、SSRとWeb APPを同時に使用する理由を検討する必要があります。 SEOにSSRが必要な場合は、SWは必要ありません。ユーザーエージェントがクローラーの場合はSSRを実行し、クライアントが通常のユーザーの場合は動的にangularを提供します。

ユーザーエージェントに基づいてリクエストを切り替える方法

これは私の考えであり、誰かがこれを行っているかどうかはわかりません。しかし、理論的には、うまくいくはずです。

まず、サーバー側とクライアント側のレンダリング構成を使用して、2つの異なるディレクトリ(この例ではDIST_FOLDER/ssrDIST_FOLDER/csr)にアプリをビルドする必要があります。 SSRからSWを除外できます。 SWは通常どおりCSRで使用できます。

私は このパッケージ を見つけました。これはクローラー/ボットユーザーエージェントを検出できます。 expressおよびAngularの場合、次のように使用します。

app.get('*', (req, res) => {
  var CrawlerDetector = new Crawler(req)

  // check the current visitor's useragent
  if (CrawlerDetector.isCrawler())
  {
    // render the index html at server side
    res.render(path.join(DIST_FOLDER, 'ssr', 'index.html'), { req });
  }
  else {
    // serve static index.html file built without SSR and let the client render it
    res.sendFile(path.join(DIST_FOLDER, 'csr', 'index.html'));
  }
});

これを実装した後、アプリケーションをデバッグして、ユーザーエージェントを here と書かれたものに変更することで、正しく機能するかどうかを確認できます(つまり、Postmanを使用します)。

8
Gökhan Kurt