우찬쓰 개발블로그
리액트(React) CORS처리 본문
잠깐 개인적으로 리액트를 만지게 되었는데 모르던 귀찮은 에러들이 많았다.
대표적으로 교차 출처 리소스 공유(CORS)와 관련된 에러인데, 이것은 api서버쪽에서 헤더에 Access-Control-Allow-Origin을 열어주지 않는 이상 브라우저단에서 막아버리기 때문에 클라쪽에서는 방법이 없다.
그나마 해결책이 중간에 프록시서버를 두는 방법인데, 리액트 프로젝트를 사용한다면 간단하게 처리할수 있다.
다음과 같은 상황을 가정해보자. 네이버에서 코스피지수를 크롤링하려고 한다. 근데 axios로 다음과 같은 url을 호출해보니..
https://m.search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%BD%94%EC%8A%A4%ED%94%BC
export function test() {
axios.get('https://m.search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%EC%BD%94%EC%8A%A4%ED%94%BC')
.then(data => {
console.log(data.data)
})
}
바로 CORS에 걸려버렸다.
이걸 해결하는 방법은 간단하다.
package.json에 맨 아래쪽에 다음과 같이 m.serach.naver.com에 대한 프록시를 추가한다.
//package.json
{
...,
...,
"proxy": "https://m.search.naver.com"
}
그리고나서 호출할때 url의 호스트를 지워주면 된다.
export function test() {
axios.get('/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%EC%BD%94%EC%8A%A4%ED%94%BC')
.then(data => {
console.log(data.data)
})
}
이렇게 호출하면 브라우저에서는 localhost:3000 (나의 리액트 서버)로 부터 api응답 받아온것마냥 인식하기때문에 CORS가 해결된다.
그런데 이런경우 "만약 여러가지 api로부터 CORS 처리를 관리하려면 어떻게 해야하지?" 하는 의문이 들수있다.
그럴경우에는 다른 방법을 써야한다. 일단 도로 package.json에 해둔 프록시 설정을 제거하자.
그리고 http-proxy-middleware 라이브러리를 설치한다.
npm install http-proxy-middleware
설치가 끝나면 src에 setupProxy.js 파일을 하나 생성하자. (이 루트의 파일명으로 자동으로 설정되니 다른 설정은 필요없다.
//setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app){
app.use(
createProxyMiddleware('/naver', {
target: 'https://m.search.naver.com',
pathRewrite: {
'^/naver':''
},
changeOrigin: true
})
)
app.use(
createProxyMiddleware('/다른context', {
target: 'https://다른호스트',
pathRewrite: {
'^/지우려는패스':''
},
changeOrigin: true
})
)
...
};
위처럼 설정하면 '/naver'로 시작되는 url을 자동으로 인식하여 프록시 처리해주고, /naver라는 패스는 pathRewrite에서 설정한 것처럼 제거가 가능하다.
그래서 이렇게 호출하면 관리가 가능하다.
export function test() {
axios.get('naver/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%EC%BD%94%EC%8A%A4%ED%94%BC')
.then(data => {
console.log(data.data)
})
}
CORS 해결책을 찾아 헤매는 누군가에게 도움이 되기를..