アングルサーバ側レンダリング(SSR):ブラウザはサーバーではありません
4757 ワード
SSRについての大きなことの一つは、我々は我々のフロントエンドと私たちのバックエンドで我々のアプリをレンダリングするために同じコードを使用するようになることです.まあ、ソート.
我々が同じコードを使うとき、我々には問題があります:ブラウザーはサーバーでありません、そして、我々が各々の環境でできることの違いがあります.
サーバー上で我々の角度アプリをレンダリングする利点は、我々がブラウザに何かを送信する前に、個人的かつ効率的にデータを取得することができますです.
私たちのサーバーは(この場合)ノードです.JSなどのサーバが利用できます.
あなたがサーバーで望む他の何かへのアクセス:Redis、AWSサービス、データベースなど.
何がSSRを破ることができますか?
さて、ブラウザには三つのことが考えられます.
以下は、私はあなたにそれを行うためのテクニックの一つを示すつもりです
国際化の追加
アプリケーションに国際化を加えましょう.つの通貨で製品価格を表示しましょう:米ドル、英国ポンド、ポーランドZloty.アプリケーションは、ブラウザの設定に基づいて通貨を選択する必要がありますし、指定された言語がサポートされていない場合、それはポーランドZloty
新しいサービスを生成しましょう
ng g s sample
ユーザー言語を検出し、3つの利用可能な通貨コードのうちの1つを返すgetCurrencyCode ()メソッドを実装しましょう. providedIn: 'root'
})
export class SampleService {
private userLang;
constructor() {
this.userLang = window.navigator.language;
}
public getCurrencyCode(): string {
switch(this.userLang) {
default:
case 'pl-PL': return 'PLN';
case 'en-US': return 'USD';
case 'en-EN': return 'GBP';
}
}
}
コンポーネントのいずれかで、PropertDetailsComponentというように、このサービスを使用してユーザーの通貨を取得できます.public userCurrency: string = this.sampleService.getCurrencyCode();
constructor(
private route: ActivatedRoute,
private ps: ProductsService,
private us: UserService,
private sampleService: SampleService
) { }
次に、通貨パイプでビューでユーザー通貨を使用できます.<pclass="text-muted">{{userCurrency}}</p>
今後、価格はユーザーのローカライズ設定によって定義された通貨で表示する必要があります.これは素晴らしいですか?残念ながら、このロジックはSSRを壊します。
ERROR: ReferenceError: window is not defined
現在のランタイムがブラウザかサーバであるかどうかを検出する機構があれば、それが役に立つでしょう.isplatformbrowser ()およびisplatformserver ()
@ angle/commonパッケージのisplatformbrowser ()およびisplatformserver ()メソッドを持つ角の船.これらのメソッドの各々は、1つのパラメタを受け入れます:プラットホームID.
上記の国際化サービスI 18 NServiceを変更するには、次の新しいインポートを追加します.
import {
Injectable,
Inject,
PLATFORM_ID
} from '@angular/core';
import {
isPlatformBrowser
} from '@angular/common';
サービスコンストラクタを変更して、サービスのインスタンスがブラウザで実行された場合にのみウィンドウオブジェクトを使用します.export class SampleService {
constructor(
@Inject(PLATFORM_ID)
private platformId: any
) {
if (isPlatformBrowser(this.platformId)) {
this.userLang =
window.navigator.language;
} else {
// server specific logic
}
}
// ...
}
これはSSRが再び動作を開始するのに十分なはずですが、サーバー側のレンダリングにプリプレインされた国際化を取得しません.国際化はアプリケーションのロード後に表示されません.それで、我々が必要とするものは、起源HTTPリクエストからサーバーにどんな言語を与えるかを知る方法です.
リクエストオブジェクト
問題は、サーバー上のユーザー言語に関する情報を取得する方法です.それは可能ですか?
はい.
ブラウザから要求を実行しているときは、ブラウザは通常、あなたが考えないかもしれないHTTPヘッダの束を追加します.
これらのヘッダーの1つは、ユーザーが望む言語を教えて受け入れる言語です!
例えば、ヘッダは以下のようにやってくるかもしれません.q = 0.5
リクエストからヘッダを取得する
角のUniversalを使用すると、HTTPリクエストを表すオブジェクトを取得できます.@ ngUniversal/Express Engine/Tokensパッケージからリクエストトークンの下で依存関係インジェクションによって利用可能です.requestオブジェクトは以下のフィールドを含みます:
import { Injectable, Inject, PLATFORM_ID, Optional } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { REQUEST } from '@nguniversal/express-engine/tokens';
import { Request } from 'express';
Constructorを変更して、Accept Languageヘッダーから要求オブジェクトを入力し、ユーザー言語を取得しますexport class SampleService {
constructor(
@Inject(PLATFORM_ID) private platformId: any,
@Optional()
@Inject(REQUEST) private request: Request
) {
if (isPlatformBrowser(this.platformId)) {
this.userLang =
window.navigator.language;
} else {
this.userLang = (
this.request.headers[
"accept-language"
] || ""
).substring(0, 5);
}
}
// ...
}
Reference
この問題について(アングルサーバ側レンダリング(SSR):ブラウザはサーバーではありません), 我々は、より多くの情報をここで見つけました https://dev.to/deekshithrajbasa/angular-server-side-rendering-ssr-the-browser-is-not-the-server-30a5テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol