๊ด€๋ฆฌ ๋ฉ”๋‰ด

Daily Front_Minhhk

React Proxy ๋ณธ๋ฌธ

Code๊ฐœ๋ฐœ์ผ์ง€

React Proxy

Minhhk 2023. 2. 6. 16:33
๐Ÿ’ก CORS - ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ , (Cross-Origin Resource Sharing, CORS)
์ถ”๊ฐ€ HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ž…๋‹ˆ๋‹ค.

 

CORS ์ •์ฑ…์„ ์œ„๋ฐ˜ ํ•˜์—ฌ ๋‹ค๋ฅธ ์ถœ์ฒ˜๋ฅผ ๊ฐ€์ง„ ์ƒํƒœ์—์„œ ์š”์ฒญํ•˜๊ฒŒ ๋˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ณด์•ˆ์ƒ์˜ ์ด์œ ๋กœ ์ฐจ๋‹จํ•œ๋‹ค

ํด๋ผ์ด์–ธํŠธ๊ฐ€ 3000๋ฒˆ ํฌํŠธ, ์„œ๋ฒ„ ํฌํŠธ๊ฐ€ 3070 ์ผ ๋•Œ,

ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญ ํ•  ๋•Œ, CORS ์—๋Ÿฌ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.

๋™์ผํ•œ ์ถœ์ฒ˜์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๋ฉด ๋œ๋‹ค.

 

๐Ÿ’ก ๋ผ์ด๋ธŒ ๋ฐ์ดํ„ฐ(live data)
์‹ค์ œ ์„œ๋น„์Šค๋˜๊ณ  ์žˆ๋Š” ์•ฑ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(Data Base, DB)์— ์ ์žฌ๋˜๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์œ ์ € ๋ฐ ์ƒํ’ˆ, ๊ฒฐ์ œ ๋“ฑ ๋‹ค์–‘ํ•œ ์ •๋ณด๋“ค์„ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Proxy

React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ํ˜น์€ Webpack Dev Server์—์„œ ์ œ๊ณตํ•˜๋Š” proxy ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด CORS ์ •์ฑ…์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ”„๋ก์‹œ ์ ์šฉ ์ „ ํ๋ฆ„

์œ„์˜ ๊ทธ๋ฆผ์€ proxy๋ฅผ ์ ์šฉํ•ด ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์†์ด๊ธฐ ์ „ ํ๋ฆ„์ด๋‹ค.

ํ”„๋ก ํŠธ์—”๋“œ, React ์•ฑ์—์„œ ๋ธŒ๋ผ์šฐ์ € ์ชฝ์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ฐฑ์—”๋“œ, ์ฆ‰ ์„œ๋ฒ„ ์ชฝ์œผ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋•Œ ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€, ์ฆ‰ ์ถœ์ฒ˜๊ฐ€ ๊ฐ™์€์ง€ ํ™•์ธํ•˜๋Š”๋ฐ ์ด๋•Œ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” ์ •์ƒ์ ์œผ๋กœ 200 OK ์‘๋‹ต์„ ๋ธŒ๋ผ์šฐ์ €

์—๊ฒŒ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ฐ›์€ ๋ฆฌ์†Œ์Šค ๋ฐ ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ์ถœ์ฒ˜๊ฐ€ ๊ฐ™์€์ง€ ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๊ฒŒ ๋˜๋Š”๋ฐ,

์ด๋•Œ ์ถœ์ฒ˜๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด ์‘๋‹ต์„ ํŒŒ๊ธฐ(CORS Error) ํ•˜๊ณ ,

์ถœ์ฒ˜๊ฐ€ ๊ฐ™๋‹ค๋ฉด ์‘๋‹ต์„ ํŒŒ๊ธฐํ•˜์ง€ ์•Š๊ณ  ๋‹ค์‹œ ํ”„๋ก ํŠธ์—”๋“œ ์ชฝ์œผ๋กœ ์‘๋‹ต์„ ๋ณด๋‚ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ”„๋ก์‹œ ์ ์šฉ ํ›„ ํ๋ฆ„

์œ„์˜ ๊ทธ๋ฆผ์€ proxy๋ฅผ ์ ์šฉํ•ด ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์†์ธ ํ›„ ํ๋ฆ„์ด๋‹ค.

React ์•ฑ์—์„œ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด API๋ฅผ ์š”์ฒญํ•  ๋•Œ, proxy๋ฅผ ํ†ตํ•ด ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ์šฐํšŒํ•˜์—ฌ ๋ณด๋‚ธ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” ์‘๋‹ต์„ React ์•ฑ์œผ๋กœ ๋ณด๋‚ด๊ณ , React ์•ฑ์€ ๋ฐ›์€ ์‘๋‹ต์„ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ๋Œ€์‹  ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ „๋‹ฌ

ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์ถœ์ฒ˜๊ฐ€ ๊ฐ™์•„์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ €๋Š” ํ—ˆ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์›น ๊ฐœ๋ฐœ์—์„œ Proxy ์‚ฌ์šฉ๋ฒ• 2๊ฐ€์ง€

webpack dev server proxy

package.json ์—์„œ "proxy" ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ์ด ๋˜์–ด ์žˆ๋‹ค.

proxy๋Š” ๋ณดํ†ต ๋งจ ๋ฐ‘์— ์ž‘์„ฑ์„ ํ•ด ๊ธˆ๋ฐฉ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

...
"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
	"proxy" : "์šฐํšŒํ•  API ์ฃผ์†Œ"
}

๊ธฐ์กด์˜ fetch, ํ˜น์€ axios๋ฅผ ํ†ตํ•ด ์š”์ฒญํ•˜๋˜ ๋ถ€๋ถ„์—์„œ ๋„๋ฉ”์ธ ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•œ๋‹ค.

export async function getAllfetch() {

    const response = await fetch('์šฐํšŒํ•  api์ฃผ์†Œ/params');
    .then(() => {
			...
		})
}

export async function getAllfetch() {

    const response = await fetch('/params');
    .then(() => {
			...
		})
}

 

React Proxy ์‚ฌ์šฉ๋ฒ•

webpack dev server ์—์„œ ์ œ๊ณตํ•˜๋Š” proxy๋Š” ์ „์—ญ์ ์ธ ์„ค์ •์ด๊ธฐ ๋•Œ๋ฌธ์—,

์ข…์ข…์ ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธด๋‹ค. ๊ทธ๋ž˜์„œ ์ˆ˜๋™์œผ๋กœ proxy๋ฅผ ์ ์šฉํ•ด์ค˜์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ,

์ด๋•Œ๋Š” http-proxy-middleware ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

http-proxy-middleware ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

npm install http-proxy-middleware --save

React App์˜ src ํŒŒ์ผ ์•ˆ์—์„œ setupProxy.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ ,

์•ˆ์—์„œ ์„ค์น˜ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์™€์„œ ์ž‘์„ฑ!

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api', //proxy๊ฐ€ ํ•„์š”ํ•œ path parameter๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
    createProxyMiddleware({
      target: 'http://localhost:5000', //ํƒ€๊ฒŸ์ด ๋˜๋Š” api url๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
      changeOrigin: true, //๋Œ€์ƒ ์„œ๋ฒ„ ๊ตฌ์„ฑ์— ๋”ฐ๋ผ ํ˜ธ์ŠคํŠธ ํ—ค๋”๊ฐ€ ๋ณ€๊ฒฝ๋˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
    })
  );
};

๊ธฐ์กด์˜ fetch, ํ˜น์€ axios๋ฅผ ํ†ตํ•ด ์š”์ฒญํ•˜๋˜ ๋ถ€๋ถ„์—์„œ ๋„๋ฉ”์ธ ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•œ๋‹ค.

๋ฐ‘์˜ ๋ถ€๋ถ„์€ webpack dev server ์—์„œ ์ œ๊ณตํ•˜๋Š” proxy ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

export async function getAllfetch() {

    const response = await fetch('์šฐํšŒํ•  api์ฃผ์†Œ/params');
    .then(() => {
			...
		})
}

export async function getAllfetch() {

    const response = await fetch('/params');
    .then(() => {
			...
		})
}

'Code๊ฐœ๋ฐœ์ผ์ง€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[firebase] firestore  (0) 2023.05.01
[firebase] ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ  (0) 2023.05.01
CI / CD  (0) 2023.02.03
AWS  (0) 2023.02.02
Optimization ์ตœ์ ํ™”  (0) 2023.02.01