ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 개발 λͺ¨λ“œμ—μ„œ API μš”μ²­ν•  λ•Œ ν”„λ‘μ‹œ μ„€μ •ν•˜κΈ° Proxying API Requests in Development
    πŸ’»κ°œλ°œ/React 2023. 7. 11. 13:48
    728x90

     

     

    Proxying API Requests in Development | Create React App

    Note: this feature is available with react-scripts@0.2.3 and higher.

    create-react-app.dev

    * μ°Έκ³ : 이 κΈ°λŠ₯은 react-scripts@0.2.3 μ΄μƒμ—μ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.


    μ‚¬λžŒλ“€μ€ μ’…μ’… λ°±μ—”λ“œ κ΅¬ν˜„κ³Ό λ™μΌν•œ ν˜ΈμŠ€νŠΈ λ° ν¬νŠΈμ—μ„œ ν”„λŸ°νŠΈ μ—”λ“œ React μ•±μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

    예λ₯Ό λ“€μ–΄ μ•±μ΄ λ°°ν¬λœ ν›„ ν”„λ‘œλ•μ…˜ μ„€μ •μ€ λ‹€μŒκ³Ό κ°™μ„ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

    /             - static server returns index.html with React app
    /todos        - static server returns index.html with React app
    /api/todos    - server handles any /api/* requests using the backend implementation

    이와 κ°™μ€ μ„€μ •μ΄ μžˆμœΌλ©΄ κ°œλ°œ μ€‘에 λ‹€λ₯Έ ν˜ΈμŠ€νŠΈλ‚˜ ν¬νŠΈλ‘œ λ¦¬λ””λ ‰μ…˜ν•  μ—Όλ € μ—†μ΄ fetch('/api/todos')와 κ°™μ€ μš”청을 μž‘μ„±ν•˜λŠ” κ²ƒμ΄ νŽΈλ¦¬ν•©λ‹ˆλ‹€.

    개발 μ€‘인 API μ„œλ²„에 μ•Œ μˆ˜ μ—†λŠ” μš”청을 ν”„λ‘μ‹œν•˜λ„λ‘ κ°œλ°œ μ„œλ²„에 μ§€μ‹œν•˜λ €λ©΄ λ‹€μŒκ³Ό κ°™μ΄ package.json에 ν”„λ‘μ‹œ ν•„λ“œλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

     "proxy": "http://localhost:4000",

    μ΄λ ‡κ²Œ ν•˜λ©΄ 개발 쀑에 fetch('/api/todos')ν•  λ•Œ 개발 μ„œλ²„κ°€ 정적 μžμ‚°μ΄ μ•„λ‹˜μ„ μΈμ‹ν•˜κ³  http://localhost:4000/api/todos에 λŒ€ν•œ μš”μ²­μ„ 폴백으둜 ν”„λ‘μ‹œν•©λ‹ˆλ‹€. 개발 μ„œλ²„λŠ” Accept 헀더에 text/html이 μ—†λŠ” μš”μ²­λ§Œ ν”„λ‘μ‹œλ‘œ 보내렀고 μ‹œλ„ν•©λ‹ˆλ‹€.

    νŽΈλ¦¬ν•˜κ²Œλ„ μ΄λ ‡κ²Œ ν•˜λ©΄ κ°œλ°œ μ‹œ CORS λ¬Έμ œ λ° μ˜€λ₯˜ λ©”μ‹œμ§€λ₯Ό ν”Όν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

    Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

    ν”„λ‘μ‹œλŠ” 개발 λͺ¨λ“œ(npm start μ‚¬μš©)μ—λ§Œ 영ν–₯을 미치며 /api/todos와 같은 URL이 ν”„λ‘œλ•μ…˜ λͺ¨λ“œμ—μ„œ μ˜¬λ°”λ₯Έ ν•­λͺ©μ„ κ°€λ¦¬ν‚€λŠ”μ§€ ν™•μΈν•˜λŠ” 것은 μ‚¬μš©μžμ˜ μ±…μž„μž…λ‹ˆλ‹€.

    /api 접두사λ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. text/html 수락 헀더가 μ—†λŠ” μΈμ‹λ˜μ§€ μ•Šμ€ μš”μ²­μ€ μ§€μ •λœ ν”„λ‘μ‹œλ‘œ λ¦¬λ””λ ‰μ…˜λ©λ‹ˆλ‹€.

    ν”„λ‘μ‹œ μ˜΅μ…˜μ€ HTTP, HTTPS 및 WebSocket 연결을 μ§€μ›ν•©λ‹ˆλ‹€.

    ν”„λ‘μ‹œ μ˜΅μ…˜μ΄ μΆ©λΆ„νžˆ μœ μ—°ν•˜μ§€ μ•Šμ€ 경우 λŒ€μ•ˆμœΌλ‘œ λ‹€μŒμ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    • 직접 ν”„λ‘μ‹œ ꡬ성
    • μ„œλ²„μ—μ„œ CORSλ₯Ό ν™œμ„±ν™”ν•©λ‹ˆλ‹€.
    • ν™˜κ²½ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ˜¬λ°”λ₯Έ μ„œλ²„ 호슀트 및 포트λ₯Ό 앱에 μ‚½μž…ν•˜μ‹­μ‹œμ˜€.

    ν”„λ‘μ‹œ ꡬ성 ν›„ "잘λͺ»λœ 호슀트 헀더" 였λ₯˜

    "Invalid Host Header" Errors After Configuring Proxy

    ν”„λ‘μ‹œ μ˜΅μ…˜μ„ ν™œμ„±ν™”ν•˜λ©΄ 보닀 μ—„κ²©ν•œ 호슀트 검사 μ„ΈνŠΈλ₯Ό μ˜΅νŠΈμΈν•˜κ²Œ λ©λ‹ˆλ‹€. μ΄λŠ” λ°±μ—”λ“œλ₯Ό 원격 ν˜ΈμŠ€νŠΈμ— 개방된 μƒνƒœλ‘œ 두면 컴퓨터가 DNS 리바인딩 곡격에 취약해지기 λ•Œλ¬Έμ— ν•„μš”ν•©λ‹ˆλ‹€.

    이것은 localhostμ—μ„œ κ°œλ°œν•  λ•Œ 영ν–₯을 λ―ΈμΉ˜μ§€ μ•Šμ§€λ§Œ 여기에 μ„€λͺ…λœ λŒ€λ‘œ μ›κ²©μœΌλ‘œ κ°œλ°œν•˜λŠ” 경우 ν”„λ‘μ‹œ μ˜΅μ…˜μ„ ν™œμ„±ν™”ν•œ ν›„ λΈŒλΌμš°μ €μ— λ‹€μŒ 였λ₯˜κ°€ ν‘œμ‹œλ©λ‹ˆλ‹€.

    Invalid Host header

    이 문제λ₯Ό ν•΄κ²°ν•˜λ €λ©΄ ν”„λ‘œμ νŠΈμ˜ λ£¨νŠΈμ— μžˆλŠ” .env.developmentλΌλŠ” νŒŒμΌμ— 곡개 개발 호슀트λ₯Ό 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

    HOST=mypublicdevhost.com

    μ§€κΈˆ 개발 μ„œλ²„λ₯Ό λ‹€μ‹œ μ‹œμž‘ν•˜κ³  μ§€μ •λœ ν˜ΈμŠ€νŠΈμ—μ„œ 앱을 λ‘œλ“œν•˜λ©΄ μž‘λ™ν•΄μ•Ό ν•©λ‹ˆλ‹€.

    μ—¬μ „νžˆ λ¬Έμ œκ°€ μžˆκ±°λ‚˜ ν΄λΌμš°λ“œ νŽΈμ§‘기와 κ°™μ€ μ’€ λ” μ΄κ΅­μ μΈ ν™˜κ²½μ„ μ‚¬μš©ν•˜λŠ” κ²½μš° .env.development.local에 ν•œ μ€„을 μΆ”κ°€ν•˜μ—¬ ν˜ΈμŠ€νŠΈ κ²€μ‚¬λ₯Ό μ™„μ „νžˆ μš°νšŒν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μœ„ν—˜ν•˜λ©° μ»΄ν“¨ν„°λ₯Ό μ•…μ„± μ›Ήμ‚¬μ΄νŠΈμ˜ μ›κ²© μ½”λ“œ μ‹€ν–‰μ— λ…ΈμΆœμ‹œν‚΅λ‹ˆλ‹€.

    # NOTE: THIS IS DANGEROUS!
    # It exposes your machine to attacks from the websites you visit.
    DANGEROUSLY_DISABLE_HOST_CHECK=true

    이 λ°©λ²•μ€ κΆŒμž₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.


    μˆ˜λ™μœΌλ‘œ ν”„λ‘μ‹œ κ΅¬μ„±

    Configuring the Proxy Manually

    * μ°Έκ³ : μ΄ κΈ°λŠ₯은 react-scripts@2.0.0 μ΄μƒμ—μ„œ μ‚¬μš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

    ν”„λ‘μ‹œ μ˜΅μ…˜μ΄ μΆ©λΆ„νžˆ μœ μ—°ν•˜μ§€ μ•Šμ€ κ²½μš° Express μ•± μΈμŠ€ν„΄μŠ€μ— μ§μ ‘ μ•‘μ„ΈμŠ€ν•˜κ³  κ³ μœ ν•œ ν”„λ‘μ‹œ λ―Έλ“€μ›¨μ–΄λ₯Ό μ—°κ²°ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

    이 κΈ°λŠ₯을 package.json의 ν”„λ‘μ‹œ μ†μ„±κ³Ό ν•¨κ»˜ μ‚¬μš©ν•  μˆ˜ μžˆμ§€λ§Œ λͺ¨λ“  λ…Όλ¦¬λ₯Ό src/setupProxy.js에 ν†΅ν•©ν•˜λŠ” κ²ƒμ΄ μ’‹μŠ΅λ‹ˆλ‹€.

    λ¨Όμ € npm λ˜λŠ” Yarn을 μ‚¬μš©ν•˜μ—¬ http-proxy-middlewareλ₯Ό μ„€μΉ˜ν•©λ‹ˆλ‹€.

    $ npm install http-proxy-middleware --save
    $ # or
    $ yarn add http-proxy-middleware

    λ‹€μŒμœΌλ‘œ src/setupProxy.jsλ₯Ό λ§Œλ“€κ³  κ·Έ μ•ˆμ— λ‹€μŒ λ‚΄μš©μ„ λ„£μŠ΅λ‹ˆλ‹€.

    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
      // ...
    };

    이제 μ›ν•˜λŠ” λŒ€λ‘œ ν”„λ‘μ‹œλ₯Ό λ“±λ‘ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€! λ‹€μŒμ€ μœ„μ˜ http-proxy-middlewareλ₯Ό μ‚¬μš©ν•˜λŠ” μ˜ˆμž…λ‹ˆλ‹€.

    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
      app.use(
        '/api',
        createProxyMiddleware({
          target: 'http://localhost:5000',
          changeOrigin: true,
        })
      );
    };

    μ°Έκ³ : μ΄ νŒŒμΌμ„ κ°€μ Έμ˜¬ ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€. κ°œλ°œ μ„œλ²„λ₯Ό μ‹œμž‘ν•˜λ©΄ μžλ™μœΌλ‘œ λ“±λ‘λ©λ‹ˆλ‹€.

    μ°Έκ³ : μ΄ νŒŒμΌμ€ Node의 JavaScript κ΅¬λ¬Έλ§Œ μ§€μ›ν•©λ‹ˆλ‹€. μ§€μ›λ˜λŠ” μ–Έμ–΄ κΈ°λŠ₯만 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€(즉, Flow, ES λͺ¨λ“ˆ λ“±μ„ μ§€μ›ν•˜μ§€ μ•ŠμŒ).

    μ°Έκ³ : ν”„λ‘μ‹œ κΈ°λŠ₯에 κ²½λ‘œλ₯Ό μ „λ‹¬ν•˜λ©΄ κ²½λ‘œμ—μ„œ κΈ€λ‘œλΉ™ λ°/λ˜λŠ” νŒ¨ν„΄ μΌμΉ˜λ₯Ό μ‚¬μš©ν•  μˆ˜ μžˆμœΌλ©° μ΄λŠ” μ΅μŠ€ν”„λ ˆμŠ€ κ²½λ‘œ μΌμΉ˜λ³΄λ‹€ λ” μœ μ—°ν•©λ‹ˆλ‹€.