리액트 새로고침 시 404 에러 / url 별 was 요청 구분

2023. 3. 30. 13:17Others/Error

728x90
반응형

웹서버에 리액트 배포시 자주 접하는 에러로

루트페이지 '/' 가 아닌 곳에서 새로고침을 하거나, url을 직접 타이핑 쳐 이동할 경우 404 에러가 나는 경우가 많다.

 

이는 리액트는 소스의 루트 경로에 있는 index.html 파일 하나만을 파싱하며, 내부에서 페이지를 이동할 경우

index.html의  root div에 컴포넌트를 교체하여 리렌더링하는 식으로 화면을 변환하는데,

새로고침하거나 url을 직접 타이핑 쳐 이동하려할 경우, 해당 경로에 있는 물리적인 파일을 찾으려 하기 때문에 404에러가 나는 것.

 

예를 들어 domin.com/login/loginPage 페이지로 이동하려 할 경우,

화면에서 a태그를 클릭하거나 useNavigate 등을 통해 이동하면, 리액트에서 우리가 미리 작성해놓은 라우팅을 통해

index.html의 컴포넌트를 loginPage 라우팅 경로에 맞는 컴포넌트로 교체해주어 화면을 이동하지만,

 

해당 경로에서 새로고침하거나 url을 타이핑 쳐 이동하려할 경우

index.html이 있는 root 폴더로부터 login 폴더의 loginPage 파일을 찾으려 하는데, 우리는 해당 파일이 없으니 404 에러가 나는 것이다.

 

이를 해결하려면 웹서버로 들어오는 요청들에 대해 index.html을 리턴해주면 된다.

 

1. Nginx의 경우

- nginx.conf

server{
	listen 80;
    server_name localhost;
    index index.html;
    
    location / {
    	root /usr/share/nginxx/html/build;  #react 빌드 폴더
        index index.html index.htm;         #nginx index파일
        try_files $uri $uro/ / index.html;  #모든 uri에 대해 index.html 파일을 리턴한다
    }
}

 

2. Apache의 경우

- .htaccess

먼저 리액트 소스의 index.html이 있는 root 폴더에 .htaccess 파일을 작성해준다.

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

 

- host.conf 혹은 웹서버 VirtualHost를 설정하는 설정파일

<VirtualHost *:443>
	DocumentRoot "배포경로"
    <Directory "배포경로">
    	Options FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        Allow from all
        <LimitExcept GET POST HEAD>
        	require all denied
        </LimitExcept>
        LimitRequestBody 5000000
    </Directory>
    
    ...
    
</VirtualHost>

아파치,톰캣을 사용한다면 mod_jk 파일에서 설정을 할 수도 있고,

ssl을 이용한 https 접근인지, http 접근인지에 따라 사용하는 설정파일이 다를 수 있으니 확인하고 수정한다.

 

.htaccess 파일에서 rewrite engine을 이용해, 들어오는 요청들에 대해 재정의하여 다른 파일을 찾지 않고 index.html을 다시 내보내준다.

또한 .htaccess 파일에 대한 사용을 허가하도록 설정파일에서 AllowOverride 관련 설정을 작성해준다.

 

 

 


 

3. uri 별 was로 보내는 요청 구분

react를 웹서버에 올리고, was에 react와 연동할 프로그램을 올린다면

 

대부분의 페이지 요청들은 리액트에서 자체적으로 처리하며 (useNavigate 등) was로 요청을 보내지 않고 was에서 자체적으로 요청을 처리해야 한다.

 

axios등을 통해서만 was로 요청을 보내고 싶을 경우,

내가 처음 사용했던 방법은

 - axios의 요청을 보낼 주소에 was 서버의 ip까지 직접 입력

axios.post('http://000.000.000.000/api/test',data)

위와 같이 주소에 uri만 입력하는 것이 아니라 was서버의 ip까지 입력하는 방법이 있다.

 

하지만 was서버가 외부에서 접속할 수 없는 공인 ip가 없고 web server하고만 연결이 되어있다면,

위처럼 axios에서 ip로 접근할 수 없고, 웹서버를 통해서만 요청을 보낼 수 있는데 이같은 경우에는

 

- 웹서버 설정파일에서 was로 요청을 보낼 uri 구분

axios.post('/api/test',data)

 

- 위 404에러를 처리했던 설정파일

<VirtualHost>
	<Directory>
    
    	...
        
    </Directory>
    
    ...
    
    JkMount /api|/* was_portal
</VirtualHost>

/api 혹은 /api/*로 들어오는 요청만 웹서버에서 설정한, 연결된 was로 요청을 보낸다. (was_portal은 설정한 연결한 was 이름)

 

728x90
반응형

'Others > Error' 카테고리의 다른 글

fk 참조시 null값과 공백값의 차이  (0) 2023.03.29
스키마/테이블 접근 에러, does not exist  (0) 2023.03.29