web-dev-qa-db-ja.com

Vue.jsルーター:履歴モードとAWS S3(RoutingRules)

Amazon S3とCloudflareでVue.jsアプリケーションを稼働させています。

インデックスを開いて/ dashboardを参照すると、すべてが正常に機能します。しかし、ダッシュボードなどのルートを新しいタブで直接開くか、ページを更新すると、S3から次のエラーが返されます。

404 Not Found

Code: NoSuchKey
Message: The specified key does not exist.
Key: unternehmen
RequestId: 6514F8A1F4C29235
HostId: +BVrPLJSGdzSYogzWZ4GMBXkgkdSJWRVJVhcSs4EI/lmMUR422aCtCxpBGU6AMe5VkS1UbEn/Lc=

問題はVue.js履歴モードであることを読んでください: https://router.vuejs.org/de/essentials/history-mode.html

Amazon S3バケットのルーティングルールの問題を解決したいと思います。 Apache RewriteRuleはどのようにS3を探しますか?

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

以下を試しましたが、機能しません。

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>domain.com</HostName>
      <ReplaceKeyWith>index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

このようにすると、ヘッダーとフッターがレンダリングされるだけで、それ以上はレンダリングされません。

ありがとうございました!

17
mrks

私はこの答えが遅くなることを知っていますが、他の誰かがcloudfrontでこれを解決する別の方法を探している場合、ページが見つからないときにs3リダイレクトユーザーにカスタムページを作成する必要はありません。それを行う代わりに、カスタムエラー応答をクラウドフロントで作成して配布できます。

Custom errors

これにより、ファイルが見つからない場合に常に/index.htmlにリダイレクトされ、アプリルートがトリガーされます。

38
Mindastic

私はVueで作成された静的PWAを「静的Webサイトホスティング」を使用してS3でホストしており、期待どおりに機能します。私がしたことは非常に簡単でした-これを追加しました:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith></ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

S3バケットのプロパティへ。下の画像を参照してください: S3 Properties

私のS3バケットでは、存在しないファイルにアクセスしようとするたびに、404ではなく403(禁止)が返されます。そのため、HttpErrorCodeReturnedEqualsを403に変更しました。ReplaceKeyWithを正しいルートをトリガーしないため、 "index.html"のような空の文字列。

お役に立てば幸いです。

乾杯、アレックス

4

この問題には2つの要素があると思います。

1。

/ jobsなどのサブパスに直接(Javascriptアプリの外で)リクエストが行われた場合、パス/オブジェクトが存在しないため、S3は404を返します。これを修正する最も簡単な方法は、S3自体からで、すべてのエラーページをindex.htmlにリダイレクトします。

ただし、これはCloudfrontなどのCDNでは機能せず、おそらくCloudflareでも機能しません。

良いトリックは、次のようにユーザーをリダイレクトするS3内のファイルを使用することです。

ジョブ/-> /index.htmlジョブ-> /index.html

たとえば、誰かがサイトへのリクエストを行った場合、次のHTMLファイルを取得します。

"redirect":"<html><head><meta http-equiv=\"refresh\" content=\"0; url=http://example.com/site/index.html\" /></head>
<body>Redirecting to <a href=\"http://example.com/site/index.html\">Home</a></body></html>"

第二に...

そのようにすると、ヘッダーとフッターがレンダリングされますが、それ以上はレンダリングされません。

これは、ルータービューを含むコンポーネントが読み込まれているにもかかわらず、ルータービューが適切に初期化されないという問題です。

今のところ、メインの「App」コンポーネントが作成されたときにルーターをリダイレクトしています。

created () {
console.log('route', this.$route.path)
this.$router.replace(this.$route.query.redirect || '/')
}

これには、ルータービューをレンダリングするように強制しながら、パスからindex.htmlを削除する(新しいリダイレクトによってそこに配置された)ボーナスが追加されています...

#appコンポーネントは親コンポーネントで、ナビゲーションバー、フッター、およびすべてのサブページ/コンポーネントをレンダリングするルータービューがあります。

2
comfytoday

これを履歴モードのルーティングでCloudFrontを使用せずに機能させる1つの方法は、URIが指すファイルを作成することです。たとえば、index.htmlをエントリポイントとして使用し、パスpage2.htmlを指定するページが1つだけあるとします。

次に、ビルドとデプロイのプロセスを調整して、次のことを行う必要があります。

  1. ソースをプロダクションディストリビューションにビルドします(例:npm run build
  2. ルーターリンクに対して、元のファイルのコピーであるパスごとのファイルを作成するようにしてください。この例の場合、「dist/index.html」から「dist/page2.html」へのコピーを作成することになります。
  3. Distフォルダーの内容をS3バケットにコピーします

ステップ1と2の順序が重要であることに注意してください。これは、Webサイトを公開するスクリプトで簡単に実行できます。私はこのアプローチを使用したばかりで、望んだ結果が得られました。ページの更新を許可し、新しいタブでリンクを開く。

私が目にする欠点は次のとおりです。-ファイルのコピーを保存するオーバーヘッド-ビルドスクリプトとデプロイスクリプトの更新を忘れないようにページを追加するかどうかを確認する必要があります。

0
user35800

AWS S3で静的ホスティングを使用していて、これがSPAアプリ(React、Vue、Angular etc))である場合、index.htmlをエラーページとして設定する必要があります: enter image description here