웹팩의 devServer를 이용해서 프록시 요청을 보내는 방법을 알아봅시다.
참고 자료: 웹팩 공식문서 - devserverproxy
사진과 같은 상황이라고 가정하고
프록시 적용방법을 먼저 말씀드리면 다음과 같습니다.
vue-cli 프로젝트의 루트 디렉토리(package.json 파일이 있는 위치) 에서 vue.config.js 라는 파일을 만들어줍니다.
vue.config.js 파일에 다음과 같이 작성해줍니다.
// 파일 경로: /root/vue.config.js
module.exports = {
// 개발 서버 설정
devServer: {
// 프록시 설정
proxy: {
// 프록시 요청을 보낼 api의 시작 부분
'/api': {
// 프록시 요청을 보낼 서버의 주소
target: 'http://localhost:3000'
}
}
}
};
vue.config.js 와 같은 설정 파일은 핫 로딩이 지원되지 않습니다. 개발서버를 재실행합니다.
// vue cli 3.x 버전 이상일 때 개발서버 실행 기본 명령어
npm run serve
잘 받아왔습니다.
만약, http://localhost:3000/api/getList 로 요청을 보냈는데 브라우저에는 8080으로 찍혔다는 것이 궁금하다면 다음을 읽어주세요.
package.json 에는 다음과 같이 작성되어 있습니다.
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
npm run serve 명령어를 수행하면 결과적으로 다음과 같은 명령어가 수행됩니다.
vue-cli-service serve
vue cli 공식문서에는 다음과 같이 작성되어 있습니다.
vue-cli-service serve명령은 webpack-dev-server 기반의 dev 서버를 즉시 시작합니다.
여기까지 정리하면,
npm run serve 명령은 webpack-dev-server를 실행시킵니다.
npm run serve 명령을 수행하면 localhost의 8080 포트로 개발서버를 실행합니다.
따라서, 브라우저로 http://localhost:8080 요청을 보내게 되면, HTML, JavaScript, CSS 를 응답으로 받고
자바스크립트가 index.html 의 <div id="app"></div>
부분에 vue 컴포넌트를 동적으로 그려줍니다.
참고사항으로 vue-router 를 이용해서 /login으로 라우팅하는 경우
http://localhost:8080/login 으로 http 요청을 보내지 않습니다.
URL 만 변경되고, index.html 의 <div id="app"></div>
부분을 라우터에 매핑된 컴포넌트로 바꿔줍니다.
다음과 같이 http://localhost:8080 에서 실행중인 웹 애플리케이션이http://localhost:3000/api/getList 로 http 요청을 보내는 경우 CORS 가 발생합니다.
웹 애플리케이션이 1) 도메인, 2) 포트, 3) 프로토콜이 다른 곳으로 요청을 보낼 수 없도록 브라우저가 요청을 막는 정책입니다.
서버에서 접근을 허용해주면됩니다.
//node.js express 서버의 예시
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
웹 애플리케이션이 1) 도메인, 2) 포트, 3) 프로토콜이 같은 서버에 요청을 보내고 그 서버가 대신해서 다른 서버에 요청을 다시 보내고 응답을 돌려줍니다.
proxy 영어 단어의 원래 의미는 대리, 대신입니다.
프록시 서버의 의미는 대리로 해주는 서버
무엇을 대신 해주나면 요청을 대신해줍니다.
즉, 클라이언트(브라우저)와 서버 사이에서 중요청과 응답을 대신 보내고 받는 역할을 하는 서버를 프록시 서버라고 부릅니다.
위와 같은 프로세스로 요청하기 때문에
브라우저는 3000 포트에서 실행되는 서버의 자원을 받지만
브라우저는 실제로 http://localhost:8080/api/getList 로 요청을 보냅니다.
그리고, 웹 애플리케이션이 요청을 보낸것이 아니기 때문에 CORS에 걸리지 않습니다.
// vue create '생성할 프로젝트 이름'
vue create vue_proxy
npm i axios
root 는 package.json 파일이 있는 최상단 위치
// 파일 경로: /root/vue.config.js
module.exports = {
// 개발 서버 설정
devServer: {
// 프록시 설정
proxy: {
// 프록시 요청을 보낼 api의 시작 부분
'/api': {
// 프록시 요청을 보낼 서버의 주소
target: 'http://localhost:3000'
}
}
}
};
// 웹팩 개발 서버 실행
npm run serve
// 파일 경로: /root/src/App.vue
<template>
<div id="app">
main
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'App',
created() {
// 1. 브라우저에서 직접 요청
this.corsRequest()
// 2. 개발 서버를 이용해서 프록시 요청
this.proxyRequest()
},
methods: {
corsRequest() {
axios.get("http://localhost:3000/api/getList")
.then((res) => {
console.log('corsRequest res', res)
})
.catch((error) => {
console.log('corsRequest error', error)
})
},
proxyRequest() {
axios.get("/api/getList")
.then((res) => {
console.log('proxyRequest res', res)
})
.catch((error) => {
console.log('proxyRequest error', error)
})
}
}
}
</script>
// 글로벌 옵션으로 express 설치
npm i express
var express = require('express');
var app = express();
// http://localhost:3000/api/getList 에 컨트롤러 매핑
app.get('/api/getList', function(req, res) {
res.send('api getList');
});
app.listen(3000);
node server.js
다음과 같이 1) 도메인, 2) 포트가 다른 서버에 보낸 요청은 CORS에 에러가 발생했습니다.
하지만, 프록시 요청은 응답을 제대로 받아왔습니다.
뷰초보인데... 깔끔하게 정리된글 감사드립니다.
궁금한게있는데요.. 실제 배포 될때는 어떻게 되는건가요?
proxy까지 같이 배포가 되나요?(proxy는 서버인데 실제 배포는 vue 클라이언트만 되잖아요?)
그렇다면 아래와 같은 요청의 외부 host는 어디에 정의가 되나요?
axios.get("/api/getList")