vue proxy 사용하기

skyepodium·2020년 6월 20일
7
post-thumbnail
post-custom-banner

웹팩의 devServer를 이용해서 프록시 요청을 보내는 방법을 알아봅시다.
참고 자료: 웹팩 공식문서 - devserverproxy

  • 개발 환경
    vue-cli 3.x 버전 이상
    (사실, vue-cli 2.x 버전도 큰 차이는 없는데요 파일명이랑 위치랑, 이런것들이 조금 달라요.)

1. 결론

사진과 같은 상황이라고 가정하고

프록시 적용방법을 먼저 말씀드리면 다음과 같습니다.

1) vue.config.js

vue-cli 프로젝트의 루트 디렉토리(package.json 파일이 있는 위치) 에서 vue.config.js 라는 파일을 만들어줍니다.

2) devServer 설정

vue.config.js 파일에 다음과 같이 작성해줍니다.

// 파일 경로: /root/vue.config.js

module.exports = {
        // 개발 서버 설정
        devServer: {
            // 프록시 설정
            proxy: {
                // 프록시 요청을 보낼 api의 시작 부분
                '/api': {
                    // 프록시 요청을 보낼 서버의 주소
                    target: 'http://localhost:3000'
                }
            }
        }
};

3) 실행

vue.config.js 와 같은 설정 파일은 핫 로딩이 지원되지 않습니다. 개발서버를 재실행합니다.

// vue cli 3.x 버전 이상일 때 개발서버 실행 기본 명령어
npm run serve

4) 확인

잘 받아왔습니다.

만약, http://localhost:3000/api/getList 로 요청을 보냈는데 브라우저에는 8080으로 찍혔다는 것이 궁금하다면 다음을 읽어주세요.

2. 웹팩 개발서버

1) npm run serve

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를 실행시킵니다.

2) webpack-dev-server

npm run serve 명령을 수행하면 localhost의 8080 포트로 개발서버를 실행합니다.

따라서, 브라우저로 http://localhost:8080 요청을 보내게 되면, HTML, JavaScript, CSS 를 응답으로 받고

자바스크립트가 index.html 의 <div id="app"></div> 부분에 vue 컴포넌트를 동적으로 그려줍니다.

3) 라우팅

참고사항으로 vue-router 를 이용해서 /login으로 라우팅하는 경우
http://localhost:8080/login 으로 http 요청을 보내지 않습니다.
URL 만 변경되고, index.html 의 <div id="app"></div> 부분을 라우터에 매핑된 컴포넌트로 바꿔줍니다.

3. 브라우저에서 HTTP 요청

1) 브라우저에서 직접요청

다음과 같이 http://localhost:8080 에서 실행중인 웹 애플리케이션이http://localhost:3000/api/getList 로 http 요청을 보내는 경우 CORS 가 발생합니다.

2) CORS

웹 애플리케이션이 1) 도메인, 2) 포트, 3) 프로토콜이 다른 곳으로 요청을 보낼 수 없도록 브라우저가 요청을 막는 정책입니다.

3) CORS 해결방법

  • 첫번째 방법 - 서버에서 해결 (권장 x)

서버에서 접근을 허용해주면됩니다.

//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 영어 단어의 원래 의미는 대리, 대신입니다.

프록시 서버의 의미는 대리로 해주는 서버

무엇을 대신 해주나면 요청을 대신해줍니다.

즉, 클라이언트(브라우저)와 서버 사이에서 중요청과 응답을 대신 보내고 받는 역할을 하는 서버를 프록시 서버라고 부릅니다.

4. 프록시 요청

위와 같은 프로세스로 요청하기 때문에

브라우저는 3000 포트에서 실행되는 서버의 자원을 받지만

브라우저는 실제로 http://localhost:8080/api/getList 로 요청을 보냅니다.

그리고, 웹 애플리케이션이 요청을 보낸것이 아니기 때문에 CORS에 걸리지 않습니다.

5. 실습

1) vue 프로젝트 생성

// vue create '생성할 프로젝트 이름'
vue create vue_proxy

2) axios 설치

npm i axios

3) vue.config.js 생성

root 는 package.json 파일이 있는 최상단 위치

// 파일 경로: /root/vue.config.js

module.exports = {
        // 개발 서버 설정
        devServer: {
            // 프록시 설정
            proxy: {
                // 프록시 요청을 보낼 api의 시작 부분
                '/api': {
                    // 프록시 요청을 보낼 서버의 주소
                    target: 'http://localhost:3000'
                }
            }
        }
};

4) npm run serve

// 웹팩 개발 서버 실행
npm run serve

5) App.vue 수정

// 파일 경로: /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>

6) express 설치

// 글로벌 옵션으로 express 설치
npm i express

7) server.js 작성

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);

8) express 서버 실행

node server.js

9) 확인

다음과 같이 1) 도메인, 2) 포트가 다른 서버에 보낸 요청은 CORS에 에러가 발생했습니다.

하지만, 프록시 요청은 응답을 제대로 받아왔습니다.

profile
callmeskye
post-custom-banner

4개의 댓글

comment-user-thumbnail
2020년 9월 3일

뷰초보인데... 깔끔하게 정리된글 감사드립니다.
궁금한게있는데요.. 실제 배포 될때는 어떻게 되는건가요?
proxy까지 같이 배포가 되나요?(proxy는 서버인데 실제 배포는 vue 클라이언트만 되잖아요?)
그렇다면 아래와 같은 요청의 외부 host는 어디에 정의가 되나요?
axios.get("/api/getList")

2개의 답글
comment-user-thumbnail
2023년 3월 25일

글 정말 잘 보았고 프록시에 대한 이해에 도움이 많이 되었어요. 감사합니다.

  1. 프록시 요청 부분에
    8000포트가 아니라 8080 포트인것같아요!!
답글 달기