S3静的Webサイトホスティングは、Index.htmlへのすべてのパスをルーティングします


250

私はS3を使用して、HTML5 pushStatesを使用するJavaScriptアプリをホストしています。問題は、ユーザーがいずれかのURLをブックマークした場合、何にも解決されないことです。必要なのは、完全なリダイレクトを行うだけでなく、すべてのURLリクエストを取得し、S3バケットでルートindex.htmlを提供する機能です。その後、私のJavaScriptアプリケーションはURLを解析して適切なページを提供できます。

リダイレクトを行う代わりに、すべてのURLリクエストに対してindex.htmlを提供するようにS3に指示する方法はありますか?これは、次の例のように単一のindex.htmlを提供することにより、すべての着信要求を処理するようにApacheを設定するのと似ています。これらのルートを処理するためだけにWebサーバーを実行することは避けたいです。S3からすべてを実行することは非常に魅力的です。


これに対する解決策を見つけましたか?
w2lame 2014

回答:


302

CloudFrontのヘルプがあれば、URLをハックすることなく簡単に解決できます。

  • S3バケットを作成します。例:react
  • 次の設定でCloudFrontディストリビューションを作成します。
    • デフォルトのルートオブジェクト:index.html
    • 元のドメイン名:S3バケットドメイン、例:react.s3.amazonaws.com
  • 移動しますページのエラーをクリックし、タブをカスタムエラーレスポンスを作成します
    • HTTPエラーコード:403:禁止(404:S3静的Webサイトの場合は見つかりません)
    • エラー応答のカスタマイズ:はい
    • 応答ページのパス:/index.html
    • HTTP応答コード:200:OK
    • 作成をクリックします

8
ありがとう。これまでのベストアンサー。
jgb 2016年

そして、あなたが「自然な」ルーティングを行うことができるようにあなたが場所を保つのがそれほど明白でないこと
Lukasz Marek Sielski、2016年

5
これは私にとって魅力のように働いた、私は必要なだけカスタムエラーコードは、404 403ではなかった
ジェレミーS.

4
少しハックしましたが、うまく機能します:) CloudFrontがパスの範囲をS3ファイルに(リダイレクトせずに)マッピングできるようにしておくとよいでしょう。
Bob

3
これは私のために働いていません。このソリューションは常に正しいページではなくホームページにリダイレクトします...
Jim

201

これを機能させる方法は次のとおりです。

ドメインのS3コンソールの[ リダイレクトルール編集]セクションで、次のルールを追加します。

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>yourdomainname.com</HostName>
      <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

これにより、404が見つからないすべてのパスが、ハッシュバングバージョンのパスを使用してルートドメインにリダイレクトされます。したがって、/ postsにファイルがない場合、http://yourdomainname.com/postshttp://yourdomainname.com/#!/postsにリダイレクトされます。

ただし、HTML5 pushStatesを使用するには、このリクエストを受け取り、ハッシュバングパスに基づいて適切なpushStateを手動で確立する必要があります。したがって、これをindex.htmlファイルの先頭に追加します。

<script>
  history.pushState({}, "entry page", location.hash.substring(1));
</script>

これによりハッシュが取得され、HTML5 pushStateに変換されます。この時点から、pushStatesを使用して、ハッシュバン以外のパスをアプリに含めることができます。


4
このソリューションはうまく機能します!実際、htmlモードが設定されている場合、angularjsは自動的に履歴pushStateを実行します。
wcandillon 2013年

1
URLにGETパラメータが含まれている場合、これは古いバージョンのIEでは失敗しますよね?どのようにその問題を回避しますか?
clexmond 2014年

3
ありがとう!これは、小さな調整を加えたバックボーンで私にとってはうまくいきました。古いブラウザのチェックに追加しました: <script language="javascript"> if (typeof(window.history.pushState) == 'function') { window.history.pushState(null, "Site Name", window.location.hash.substring(2)); } else { window.location.hash = window.location.hash.substring(2); } </script>
AE Grey

10
react-routerHTML5 pushStatesと<ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith>
Felix D

5
これはサファリでは機能せず、展開戦略に大きな問題があります。リダイレクトする小さなjsを書くのは、ちょっと粗末なアプローチです。また、リダイレクトの数も問題です。すべてのS3 URLが常にindex.htmlを指す方法があるかどうかを考えています。
moha297 2016

129

他の人が述べたS3 / Redirectベースのアプローチにはいくつかの問題があります。

  1. アプリのパスが解決されると、複数のリダイレクトが発生します。例:www.myapp.com/path/for/testはwww.myapp.com/#/path/for/testとしてリダイレクトされます
  2. SPAフレームワークのアクションが原因で「#」が出入りするときに、URLバーにちらつきがあります。
  3. seoが影響を受けるのは、「Hey!そのグーグルはリダイレクトに彼の手を強制します
  4. アプリのSafariサポートは簡単です。

解決策は次のとおりです。

  1. ウェブサイトにインデックスルートが設定されていることを確認してください。ほとんどはindex.htmlです
  2. S3構成からルーティングルールを削除する
  3. CloudfrontをS3バケットの前に置きます。
  4. Cloudfrontインスタンスのエラーページルールを構成します。エラールールで次を指定します。

    • HTTPエラーコード:404(および必要に応じて403またはその他のエラー)
    • エラーキャッシュの最小TTL(秒):0
    • 応答のカスタマイズ:はい
    • 応答ページのパス:/index.html
    • HTTP応答コード:200

      1. SEOニーズのために、index.htmlがキャッシュされないようにするには、次のようにします。
    • EC2インスタンスを構成し、nginxサーバーをセットアップします。

    • EC2インスタンスにパブリックIPを割り当てます。
    • インスタンスとして作成したEC2インスタンスを持つELBを作成します
    • ELBをDNSに割り当てることができるはずです。
    • 次に、nginxサーバーを構成して、次のことを実行します。Proxy_passすべてのリクエストをCDNに渡し(index.htmlの場合のみ、他のアセットをクラウドフロントから直接提供します)、検索ボットの場合は、Prerender.ioなどのサービスで規定されているようにトラフィックをリダイレクトします。

nginxのセットアップについて詳しく説明します。メモを残してください。難しい方法でそれを学びました。

クラウドフロントディストリビューションの更新後。Cloudfrontキャッシュを一度無効にして、Pristineモードにします。ブラウザーでURLを押すと、すべて正常に動作するはずです。


6
ファイルが存在しない場合、S3は403 Forbiddenで応答するため、Httpエラーコード403についても上記のステップ4を繰り返す必要があると思います
Andreas

4
私にとって、これは期待される(受け入れられる)動作をもたらす唯一の答えです
mabe.berlin

1
ポイント5の@ moha297では、CDNからプロキシするnginxからフェッチするようにサイトを基本的に構成していますか(index.htmlおよびクローラーリクエストを除く)?その場合は、CDNエッジサーバーのメリットを失うことはありませんか?
Rahul Patel

2
@ moha297このコメントについて説明してください:「CDNからindex.htmlを提供してはいけません」?CloudFrontを使用してS3からindex.htmlを提供することに問題はありません。
カールG

1
0のTTLがどのように処理されるかについての詳細は、stackoverflow.com / a / 10622078/4185989を参照してください(短いバージョン:Cloudfrontによってキャッシュされますが、If-Modified-SinceGETリクエストはオリジンに送信されます)。手順5のようにサーバーを設定するには
jmq

18

これは正接ですが、S3でホストしたい(HTML5)ブラウザ履歴を備えたRacktの React Routerライブラリを使用する人のためのヒントを紹介します。

ユーザーが/foo/bearS3がホストする静的Webサイトにアクセスするとします。Davidの 以前の提案を踏まえると、リダイレクトルールはそれらをに送信します/#/foo/bear。アプリケーションがブラウザの履歴を使用して構築されている場合、これはあまり役に立ちません。ただし、アプリケーションはこの時点でロードされ、履歴を操作できるようになります。

プロジェクトにRackt 履歴を含めると(React Routerプロジェクトのカスタム履歴の使用も参照)、次の例に示すように、ハッシュ履歴パスを認識するリスナーを追加し、必要に応じてパスを置き換えることができます。

import ReactDOM from 'react-dom';

/* Application-specific details. */
const route = {};

import { Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';

const history = useRouterHistory(createHistory)();

history.listen(function (location) {
  const path = (/#(\/.*)$/.exec(location.hash) || [])[1];
  if (path) history.replace(path);
});

ReactDOM.render(
  <Router history={history} routes={route}/>,
  document.body.appendChild(document.createElement('div'))
);

要点をまとめると:

  1. DavidのS3リダイレクトルールはにリダイレクトさ/foo/bear/#/foo/bearます。
  2. アプリケーションが読み込まれます。
  3. 履歴リスナーは#/foo/bear履歴表記を検出します。
  4. そして、履歴を正しいパスに置き換えます。

Link他のすべてのブラウザ履歴機能と同様に、タグは期待どおりに機能します。私が気付いた唯一の欠点は、最初のリクエストで発生するインタースティシャルリダイレクトです。

これはAngularJSのソリューションに触発されたものであり、どのようなアプリケーションにも簡単に適応できると思います。


2
これは私にマイケルを助けました、ありがとう!履歴から参照を変更して、BrowserHistoryを使用することもできます。iebrowserHistory.listen
Marshall Moutenot

どういたしまして!お役に立ててうれしいです。また、同意し、この特定のユースケースでは、React Routerからの非推奨警告を解決するようにスニペットを更新しました。
Michael Ahlers、2016年

react-router v3.0.0はHistory v3.0.0を使用するため、react-router v3.0.0のリリースでは機能しません
Varand Pezeshkian

history.listenの無限呼び出しループを防ぐ方法はありますか?私が推測するパスを置き換えることによって引き起こされました。
Mirko Flyktman

14

この問題には4つの解決策があります。最初の3つは既に回答でカバーされており、最後の1つは私の貢献です。

  1. エラードキュメントをindex.htmlに設定します。
    問題:レスポンスの本文は正しくなりますが、ステータスコードは404になり、SEOに悪影響を及ぼします。

  2. リダイレクトルールを設定します。
    問題:で汚染されたURL #!が読み込まれ、ページが点滅する。

  3. CloudFrontを構成します。
    問題:すべてのページがオリジンから404を返すため、何もキャッシュしないか(推奨どおりTTL 0)、サイトを更新するときにキャッシュして問題が発生するかどうかを選択する必要があります。

  4. すべてのページを事前レンダリングします。
    問題:特にページが頻繁に変更される場合に、ページを事前レンダリングするための追加作業。たとえば、ニュースWebサイトです。

私の提案は、オプション4を使用することです。すべてのページを事前レンダリングする場合、予期されるページに対して404エラーは発生しません。ページは正常に読み込まれ、フレームワークが制御を取り、通常どおりSPAとして機能します。一般的なerror.htmlページを表示するようにエラードキュメントを設定し、404エラーを404.htmlページ(ハッシュバングなし)にリダイレクトするリダイレクトルールを設定することもできます。

403 Forbiddenエラーに関して、私はそれらをまったく起こさせません。私のアプリケーションでは、ホストバケット内のすべてのファイルがパブリックであると考えており、これを読み取り権限付きのEveryoneオプションで設定します。サイトに非公開のページがある場合、ユーザーにHTML レイアウトを表示させることは問題になりません。保護する必要があるのはデータであり、これはバックエンドで行われます。

また、ユーザーの写真などのプライベートアセットがある場合は、別のバケットに保存できます。プライベートアセットはデータと同じ注意が必要であり、アプリのホストに使用されるアセットファイルと比較することができないためです。


1
そして、あなたのサイトには、すべてのページを事前レンダリングするためのの優れた使用例があります。 zanon.io/posts/….- ありがとう
frekele

この4番目のアプローチは、ユーザーがpushState URLをリロードすることに対応していますか?ナビゲーションは問題なく処理されますが、リロード時にサーバーに到達します。
Alpha

@アルファさん、あなたの質問を正しく理解したかどうかはわかりませんが、リロードすると、新しいリクエストとして機能します。S3はリクエストを受け取り、事前レンダリングされたページを再び返します。この場合、サーバーはありません。
Zanon

@Zanonああ、理解できたと思う。事前にレンダリングされたページをキャッシュし、S3の存在しないリソースに移動しないようにするためのものだと思いました。これは動的な要素を持つルートを除外するでしょう?
Alpha

1
@Zanon私はついに理解しました-ありがとう!はい、そういう意味です。:)
Alpha

13

今日同じ問題に遭遇しましたが、@ Mark-Nutterの解決策は、angularjsアプリケーションからハッシュバングを削除するには不完全でした。

実際には、[ 権限の編集 ]に移動し、[ 権限追加 ]をクリックして、バケットに適切なリストを全員に追加する必要があります。この設定により、AWS S3は404エラーを返すことができるようになり、リダイレクトルールがケースを適切にキャッチします。

ちょうどこのような : ここに画像の説明を入力してください

次に、リダイレクトルールの編集に移動して、このルールを追加します。

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>subdomain.domain.fr</HostName>
            <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

ここで、SEOの目的でhashbangメソッドを使用しない場合は、HostName subdomain.domain.frを自分のドメインとKeyPrefix#!/に置き換えることができます。

もちろん、これはすべて、角度アプリケーションですでにhtml5modeを設定している場合にのみ機能します。

$locationProvider.html5Mode(true).hashPrefix('!');

これに関する私の唯一の問題は、nginxルールのようなものにはないハッシュバンのフラッシュがあることです。ユーザーはページ上にあり、更新しています:/ products / 1->#!/ products / 1-> / products / 1
Intellix

1
全員にリストのアクセス許可を与えるのではなく、403エラーのルールを追加する必要があると思います。
Hamish Moffatt 2017

11

Angular 2+アプリケーションをAmazon S3から提供し、直接URLを機能させる最も簡単なソリューションは、S3バケット構成でインデックスドキュメントとエラードキュメントの両方としてindex.htmlを指定することです。

ここに画像の説明を入力してください


11
これは、この大幅に反対された回答と同じ回答です。正常に動作しますbodyが、応答の場合のみです。ステータスコードは404になり、SEOに悪影響を及ぼします。
Zanon

これbodyは、インポートするスクリプトがある場合にのみ機能するため、headウェブサイトの
サブルートの

4

問題がまだあるので、私は別の解決策を投入します。私の場合、[mydomain] / pull-requests / [pr number] /
(例:www.example.com/pull-requests/822/ )

私の知る限り、s3ルール以外のシナリオでは、html5ルーティングを使用して1つのバケットに複数のプロジェクトを含めることができます。そのため、最も投票数の多い提案はルートフォルダーのプロジェクトで機能しますが、独自のサブフォルダーの複数のプロジェクトでは機能しません。

だから私は私のドメインを私のサーバーに向けて、nginx configに従って次の仕事をしました

location /pull-requests/ {
    try_files $uri @get_files;
}
location @get_files {
    rewrite ^\/pull-requests\/(.*) /$1 break;
    proxy_pass http://<your-amazon-bucket-url>;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @get_routes;
}

location @get_routes {
    rewrite ^\/(\w+)\/(.+) /$1/ break;
    proxy_pass http://<your-amazon-bucket-url>;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @not_found;
}

location @not_found {
    return 404;
}

ファイルを取得しようとし、見つからない場合はhtml5ルートであると想定して試行します。見つからないルートの404角度ページがある場合、@ not_foundに到達せず、見つからないファイルの代わりに角度404ページが返されます。これは、@ get_routesのifルールなどで修正できます。

私はnginxの設定の領域であまり快適ではないと言って、そのために正規表現を使用している、私はこれをいくつかの試行錯誤で動作させたので、これはうまくいく間、改善の余地があると確信していますので、あなたの考えを共有してください。

:s3リダイレクトルールがS3構成にある場合は削除してください

そしてbtwはSafariで動作します


こんにちは..ソリューションをありがとう... s3展開用にこのnginx confファイルをどこに置きますか?.exextensionsフォルダーを作成してproxy.configファイルに配置する必要があるElastic Beanstalkと同じですか?
user3124360 2017年

@ user3124360エラスティックビーンスタックについては不明ですが、私の場合、ドメイン名をec2インスタンスにポイントし、そこにnginx設定があります。したがって、要求はCLIENT-> DNS-> EC2-> S3-> CLIENTになります。
Andrew Arnautov 2017年

ええ、私は非常に似たようなことをしています... nginx設定でここにgithub.com/davezuko/react-redux-starter-kit/issues/1099 ... confファイルを投稿していただきありがとうございます...このEC2の開発方法を確認します-> S3接続を今すぐ
user3124360 2017年

3

同じ種類の問題を探していました。上記の推奨ソリューションを組み合わせて使用​​しました。

最初に、私は複数のフォルダーを持つs3バケットを持っています。各フォルダーは、react / redux Webサイトを表します。キャッシュの無効化にもcloudfrontを使用しています。

そのため、404をサポートするためにルーティングルールを使用し、それらをハッシュ構成にリダイレクトする必要がありました。

<RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website1/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website1#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website2/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website2#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website3/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website3#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

私のjsコードではbaseName、react-routerの構成で処理する必要がありました。まず第一に、あなたの依存関係が相互運用可能であることを確認してください、私history==4.0.0はと互換性がなくインストールしましたreact-router==3.0.1

私の依存関係は:

  • "履歴": "3.2.0"、
  • "反応する": "15.4.1"、
  • "react-redux": "4.4.6"、
  • "react-router": "3.0.1"、
  • "react-router-redux": "4.0.7"、

history.js履歴を読み込むためのファイルを作成しました。

import {useRouterHistory} from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';

export const browserHistory = useRouterHistory(createBrowserHistory)({
    basename: '/website1/',
});

browserHistory.listen((location) => {
    const path = (/#(.*)$/.exec(location.hash) || [])[1];
    if (path) {
        browserHistory.replace(path);
    }
});

export default browserHistory;

このコードにより、サーバーから送信された404をハッシュで処理し、ルートを読み込むためにそれらを履歴で置き換えることができます。

これで、このファイルを使用してストアとルートファイルを構成できます。

import {routerMiddleware} from 'react-router-redux';
import {applyMiddleware, compose} from 'redux';

import rootSaga from '../sagas';
import rootReducer from '../reducers';

import {createInjectSagasStore, sagaMiddleware} from './redux-sagas-injector';

import {browserHistory} from '../history';

export default function configureStore(initialState) {
    const enhancers = [
        applyMiddleware(
            sagaMiddleware,
            routerMiddleware(browserHistory),
        )];

    return createInjectSagasStore(rootReducer, rootSaga, initialState, compose(...enhancers));
}
import React, {PropTypes} from 'react';
import {Provider} from 'react-redux';
import {Router} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import variables from '!!sass-variable-loader!../../../css/variables/variables.prod.scss';
import routesFactory from '../routes';
import {browserHistory} from '../history';

const muiTheme = getMuiTheme({
    palette: {
        primary1Color: variables.baseColor,
    },
});

const Root = ({store}) => {
    const history = syncHistoryWithStore(browserHistory, store);
    const routes = routesFactory(store);

    return (
        <Provider {...{store}}>
            <MuiThemeProvider muiTheme={muiTheme}>
                <Router {...{history, routes}} />
            </MuiThemeProvider>
        </Provider>
    );
};

Root.propTypes = {
    store: PropTypes.shape({}).isRequired,
};

export default Root;

それが役に立てば幸い。この構成では、ルーティング経由でjavascriptを非同期にロードするためにreduxインジェクターと自作のsagasインジェクターを使用していることに気づくでしょう。これらの行を気にしないでください。


3

これをLambda @ Edgeで実行してパスを書き換えることができます

以下は、機能するlambda @ Edge関数です。

  1. 新しいLambda関数を作成しますが、空の関数の代わりに既存のブループリントの1つを使用します。
  2. 「cloudfront」を検索し、検索結果からcloudfront-response-generationを選択します。
  3. 関数を作成した後、内容を以下に置き換えます。また、執筆時点ではcloudfrontがノード12をサポートしていないため、ノードランタイムを10.xに変更する必要がありました。
'use strict';
exports.handler = (event, context, callback) => {

    // Extract the request from the CloudFront event that is sent to Lambda@Edge 
    var request = event.Records[0].cf.request;

    // Extract the URI from the request
    var olduri = request.uri;

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    var newuri = olduri.replace(/\/$/, '\/index.html');

    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + olduri);
    console.log("New URI: " + newuri);

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;

    return callback(null, request);
};

クラウドフロントのビヘイビアーで、それらを編集して、「Viewer Request」でそのラムダ関数の呼び出しを追加します ここに画像の説明を入力してください

完全なチュートリアル:https : //aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/


1
コードの例では1行もありません:return callback(null, request);
Pherrymason

2

React RouterとAWS Amplify Consoleで動作するソリューションを探してここに着陸した場合-Amplify ConsoleはアプリのCloudFrontディストリビューションを公開していないため、CloudFrontリダイレクトルールを直接使用できないことはすでに知っています。

ただし、解決策は非常に簡単です。次のようにAmplifyコンソールでリダイレクト/書き換えルールを追加するだけです。

React Routerのコンソール書き換えルールを増幅する

詳細(およびスクリーンショットのコピーフレンドリーなルール)については、次のリンクを参照してください。


0

これに対する答えを自分で探していました。S3はリダイレクトのみをサポートしているように見えます。URLを書き換えて、黙って別のリソースを返すことはできません。ビルドスクリプトを使用して、必要なすべてのパスの場所にindex.htmlのコピーを作成することを検討しています。多分それもあなたのために働くでしょう。


2
各パスのインデックスファイルを生成することも気になりましたが、example.com/groups/5/showのような動的パスを作成するのは難しいでしょう。この質問に対する私の答えを見ると、ほとんどの部分で問題が解決すると思います。それは少しハックですが、少なくともそれは機能します。
Mark Nutter

nginxサーバーの背後にデプロイし、すべての着信URLに対してindex.htmlを返す方が良いでしょう。私はこれをemberアプリのherokuデプロイメントで成功させました。
moha297 2016

-3

非常に単純な答えを述べるだけです。S3でホストしている場合は、ルーターのハッシュ位置戦略を使用してください。

export const AppRoutingModule:ModuleWithProviders = RouterModule.forRoot(routes、{useHash:true、scrollPositionRestoration: 'enabled'});

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.