서로 다른 도메인에서 웹서버와 node 서버 실행하기
NodeJS 실습 도중 html 과 node 서버의 실행 도메인이나 포트가 다른 경우 CORS 에러가 발생합니다. 예를 들어 html 파일은 httpd 를 통해 80포트에서 실행하고 nodejs 는 3000포트로 실행되는 경우 javascript 에서 {서버주소}:3000 으로 ajax 호출이 정상적으로 이루어지지 않습니다.
그림 1. 서로 다른 포트에서 AJAX 요청을 하는 경우 CORS 에러가 발생합니다.
이를 해결하기 위한 몇 가지 방법들을 소개합니다.
1. 같은 도메인, 포트에서 html 파일과 nodejs 서버를 실행하기
먼저 nodejs 프로젝트 폴더 안에 public 이라는 디렉토리를 만들고 모든 정적 파일들 (html, css, js, png, jpg 등) 을 복사합니다.
그리고 nodejs 에서 이런 정적 파일들을 서빙할 수 있도록 static 미들웨어를 익스프레스 app 을 만든 직후에 추가해 줍니다. 다음 코드로 static 미들웨어를 추가할 수 있습니다.
app.use(express.static('public'));
조금 더 자세한 설명은 https://expressjs.com/ko/starter/static-files.html 이 문서에서 확인 할 수 있습니다.
이제 html 파일에 접근하려면 nodejs 가 실행되는 포트로 요청하여야 합니다. 즉 다음과 같은 주소로 브라우저에서 html 파일을 요청할 수 있습니다.
http://{서버주소}:3000/index.html
2. CORS 허용 헤더 설정하기
nodejs 에서 CORS 헤더를 허용하면 다른 도메인, 포트에서 실행되고 있는 API 서버에 ajax 요청을 할 수 있습니다.
직접 이런 헤더를 설정해도 되지만 cors 미들웨어를 디펜던시에 추가하고 이를 이용하면 손쉽게 cors 설정을 할 수 있습니다. 먼저 nodejs 의 프로젝트 디렉토리 (package.json 파일이 있는 디렉토리) 에서 다음 명령으로 cors 모듈을 디펜던시에 추가합니다.
npm install cors --save
그 후 이 미들웨어를 익스프레스 app 을 만든 직후 추가해 주면 됩니다. 익스프레스 미들웨어는 등록한 순서대로 실행되기 때문에 다른 router 보다 먼저 등록해주어야 합니다. 다음 코드로 cors 미들웨어를 추가할 수 있습니다.
const cors = require('cors')
app.use(cors())
이제 서로 다른 도메인, 포트에서 ajax 요청이 차단되지 않습니다.
3. 리버스 프록시 이용하기
httpd 가 실행되고 있는 포트(일반적으로 80) 로 요청이 홨을 때 다른 포트에서 실행되는 nodejs 로 요청을 전달할 수 있습니다. 이것을 리버스 프록시라고 부릅니다. 예를들어 http://{서버주소}/api 로 오는 모든 요청을 http://{서버주소}:3000 으로 전달 할 수 있습니다. httpd 나 nginx 의 가상 호스트 설정을 변경하여 리버스 프록시를 설정할 수 있지만 전문적인 지식이 필요하므로 수업의 범위를 벗어나기 때문에 여기서 다루지는 않겠습니다. 추가로 공부하고 싶은 학생은 https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html 이 문서를 참고해 주세요.