React Router에서 빌드 된 중첩 URL을 사용하는 하위 디렉토리에있는 SPA React 앱에서 Apache를 올바르게 구성하는 방법은 무엇입니까?
내 웹 사이트가 하위 디렉토리 (예 : http : // mywebsite / admin)에 호스팅되어 있습니다. 여기서 / admin은 하위 디렉토리입니다.
내 반응 앱 (create-react-app 프로덕션 빌드)을 / admin 하위 디렉토리에 업로드했습니다. 또한 react-router v4 BrowserRouter를 사용하여 간단한 클라이언트 측 라우팅을 수행하고 있습니다. 다음은 내 반응 앱의 관련 스 니펫입니다.
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-router v4를 사용하여 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 개가 있습니다. 하나는 루트에 있고 다른 하나는 /admin하위 디렉토리에 있습니다. 둘 다 동일한 .htaccess코드를 포함합니다 . 그 이유는 루트 디렉터리에서 다른 SPA를 실행하고 있기 때문입니다.
내가 무엇을 놓치고 있습니까?
React Router에서 빌드 된 중첩 URL을 사용하는 하위 디렉토리에있는 SPA React 앱에서 Apache를 올바르게 구성하는 방법은 무엇입니까?
답변
주로 OP의 답변 및 기타 메모를 처리합니다.
이것은 내가 실수 한 곳입니다.
이제 2 개의 .htaccess가 있습니다. 하나는 루트에 있고 다른 하나는 / admin 하위 디렉토리에 있습니다. 둘 다 동일한 .htaccess 코드를 포함합니다. 그 이유는 루트 디렉터리에서 다른 SPA를 실행하고 있기 때문입니다.
이것은 반드시 "실수"가 아니 었습니다. 올바른 지시문을 사용하고 있는지 확인하기 만하면됩니다. 실제로 두 .htaccess파일을 완전히 별개의 SPA로 만들려는 경우 두 파일을 별도로 유지하는 것이 좋습니다.
두 개의 별개의 동일한 .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 경로 의 일부가 pathURL 매개 변수로 전달되지 않는다는 것 입니다. 필요한 경우이를 하드 코딩 할 수 있습니다. 예. index.html?path=admin/$1. 또는 스크립트에서 이것을 설명하십시오.
첫 번째 RewriteRule는 요청이 이미에 다시 작성된 후 추가 파일 시스템 검사를 방지하는 사소한 최적화입니다 index.html.
I가 변경된 것을 참고 (.*)(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 지시문을 완전히 재정의합니다 .
또는 반복을 피하기 위해 두 개의 개별 .htaccess파일을 유지하면서 파일에서 mod_rewrite 상속을 활성화 할 수 /admin/.htaccess있습니다. 예를 들면 ...
루트 /.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 합니다.
그러나 이것은 추가적인 복잡성 층을 추가합니다. /admin이제 SPA가 루트 .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-path에서 "admin"을 검사하는 첫 번째 조건 (부수적으로 URL-path의 모든 위치 에서 "admin"을 검사합니다 ( 엄격히 정확하지 않음))은 필요하지 않습니다. 검사는 다음에서보다 최적으로 수행 될 수 있습니다. RewriteRule지시자 자체. 예를 들면 :
RewriteRule ^(admin/.*) admin/index.html?path=$1 [QSA,L]
이 두 규칙은 원하는 경우 명확성을 희생하면서 하나로 결합 할 수 있습니다. 예를 들면 :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(admin/)?.* $1index.html?path=$0 [QSA,L]
$1역 참조는 다음 옵션 경로 접두사 중 하나가없는 admin/또는 아무것도 . 그리고 $0전체 일치를 포함합니다.
이것은 내가 실수 한 곳입니다.
이제 2 개의 .htaccess가 있습니다. 하나는 루트에 있고 다른 하나는 / 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>
도움이 되었기를 바랍니다.