Reactルーターから構築されたネストされたURLを使用するサブディレクトリにあるSPAReactアプリでApacheを適切に構成するにはどうすればよいですか?
例として、http:// mywebsite / adminなどのサブディレクトリでWebサイトをホストしています。ここで/ adminはサブディレクトリです。
/ adminサブディレクトリにreactアプリ(create-react-appプロダクションビルド)をアップロードしています。また、react-router v4 BrowserRouterを使用して、いくつかの単純なクライアント側ルーティングを実行しています。以下は私のreact-appに関連するスニペットです:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import { BrowserRouter } from 'react-router-dom';
import './css/custom.css';
ReactDOM.render(<BrowserRouter basename="/admin"><App /></BrowserRouter>, document.getElementById("root"));
App.jsxレンダリング関数内
<Route
path='/students'
render={(props) =>
<Students
{...props}
/>
}
/>
<Route
path='/teachers'
render={(props) =>
<Teachers
{...props}
/>
}
/>
すべてがうまくと、あなたがスニペットに見てきたように、主にネストされたURLを含むサイトをナビゲートする際の作業である/admin/students
と/admin/teachers
。
主な問題:/admin/teachers
ルート上でページを更新すると、ページに何も読み込まれません。リフレッシュは、/admin
ルート上でのみ機能します。しかし、そうでないときはそうではあり/admin/teachers
ません/admin/students
。
Apacheサーバーでホストされているreact-routerv4を使用してSPAを構築したのはこれが初めてではありません。以前のプロジェクトで持っていた.htaccessを再利用しました。この.htaccessは/admin
サブディレクトリにもあります。以下は.htaccess
:
.htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.html?path=$1 [NC,L,QSA]
これにより、すべてのリクエストがcreate-react-appプロダクションビルドによってビルドされたindex.htmlにルーティングされます。ただし、調査の結果、このタイプの構成は、サブディレクトリになく、ネストされたURLを使用していないプロジェクトでのみ機能します。
私は.htaccess
今2つ持っていることに注意してください。1つはルートにあり、もう1つは/admin
サブディレクトリにあります。どちらにも同じ.htaccess
コードが含まれています。これは、ルートディレクトリで別のSPAを実行しているためです。
何が足りないのですか?
Reactルーターから構築されたネストされたURLを使用するサブディレクトリにあるSPAReactアプリでApacheを適切に構成するにはどうすればよいですか?
回答
主にOPの回答に加えて、その他の注意事項について説明します。
これは私が間違えたところです:
現在、2つの.htaccessがあることに注意してください。1つはルートにあり、もう1つは/ adminサブディレクトリにあります。どちらにも同じ.htaccessコードが含まれています。これは、ルートディレクトリで別のSPAを実行しているためです。
これは必ずしも「間違い」ではありませんでした。正しいディレクティブを使用していることを確認する必要があります。実際、.htaccess
これらが完全に別々のSPAであることが意図されている場合は、2つのファイルを別々に保つことが望ましい場合があります。
2つの別々の(同一の).htaccess
ファイルを持つための重要なポイントは次のとおりです。
- 置換文字列を相対的なものにします。スラッシュプレフィックスはありません。
RewriteBase
ディレクティブを含めないでください。(これはディレクトリプレフィックスを上書きします。)
ときにRewriteRule
置換文字列の相対パス、ディレクトリプレフィックス(すなわち。の場所.htaccess
ファイル)書き換え処理の終わりに追加されます。
だから、両方の/.htaccess
と/admin/.htaccess
同じディレクティブが含まれています:
RewriteEngine on
RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.+) index.html?path=$1 [L,QSA]
ただし、このソリューションとOPのソリューションとのわずかな違いadmin/
は、URLパスの一部がpath
URLパラメーターに渡されないことです。必要に応じて、これをハードコーディングできます。例えば。index.html?path=admin/$1
。または、スクリプトでこれを説明します。
1つ目RewriteRule
は、リクエストがに書き換えられた後のファイルシステムチェックを防ぐマイナーな最適化ですindex.html
。
(.*)
(0以上)を(.+)
(1以上)に変更したことに注意してください。これにより、ルートディレクトリを要求するときに追加のディレクトリチェックが回避されます。すなわち。example.com/
およびexample.com/admin/
。これらのリクエストを書き換えるのではなく、DirectoryIndex index.html
適切に設定されていることに依存しています。これはサーバー構成のデフォルト設定です。
以来、置換文字列(index.php?page=$1
)ドキュメントルートで、それが効果的に書き換えますと、相対的である/index.php
とする場合で/admin/.htaccess
、それが効果的に戻って書き直します/admin/index.php
。
mod_rewriteディレクティブはデフォルトでは継承されないため(他のモジュールとは異なり)、mod_rewriteディレクティブは/admin/.htaccess
親.htaccess
ファイルのmod_rewriteディレクティブを完全にオーバーライドすることに注意してください。
または、繰り返しを避けるために、2つの別々の.htaccess
ファイルを維持しながら、/admin/.htaccess
ファイルでmod_rewrite継承を有効にすることができます。例えば...
ルート/.htaccess
ファイル内:
RewriteEngine on
RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.+) index.html?path=$1 [L,QSA]
次に、/admin/.htaccess
代わりに次のようになります。
RewriteEngine On
RewriteOptions Inherit
これは、親のmod_rewriteディレクティブを、文字通りファイル内のインプレースでコピーされたかのように継承し/admin/.htaccess
ます。
ただし、これにより複雑さが増します。SPAが/admin
ルート.htaccess
ファイルに依存していることを除けば、ルートファイルに破壊ディレクティブを追加しないように注意する必要があり.htaccess
ます。
余談:
RewriteCond %{REQUEST_URI} admin RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) admin/index.html?path=$1 [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.html?path=$1 [QSA,L]
URLパスの「admin」をチェックする最初の条件(ちなみに、これはURLパスのどこかで「admin」をチェックします-厳密には正しくありません)は必要ありません-チェックはでより最適に実行できますRewriteRule
ディレクティブ自体。例えば:
RewriteRule ^(admin/.*) admin/index.html?path=$1 [QSA,L]
これらの2つのルールは、必要に応じて1つに組み合わせることができますが、ある程度の明確さが犠牲になる可能性があります。例えば:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(admin/)?.* $1index.html?path=$0 [QSA,L]
$1
後方参照は、オプションのパス接頭辞、どちらか含まれているadmin/
か、何を。そして$0
、完全一致が含まれています。
これは私が間違えたところです:
現在、2つの.htaccessがあることに注意してください。1つはルートにあり、もう1つは/ adminサブディレクトリにあります。どちらにも同じ.htaccessコードが含まれています。これは、ルートディレクトリで別のSPAを実行しているためです。
単に調整私のルートを.htaccess
および削除.htaccess
/管理サブディレクトリには、主な問題は私の質問に説明固定の中にあったことを。
ルート.htaccess:
RewriteCond %{REQUEST_URI} admin
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) admin/index.html?path=$1 [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.html?path=$1 [QSA,L]
私は実際にあなたの問題に答えを知らないが、私はあなたがすることをお勧めすることができますプレーをLocation
指示。何かのようなもの
<Location "/admin">
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /admin/index.html?path=$1 [NC,L,QSA]
</Location>
お役に立てれば。