본문 바로가기
Express, Next.js/Next.js, React

[Next.js] fetch를 이용해서 api 호출하기, CORS 해결하기

by 방배킹 2024. 4. 29.

fetch

fetch(url, options)
  .then((response) => console.log("response:", response))
  .catch((error) => console.log("error:", error));

 

fetch() 함수는 JavaScript에서 서버로 네트워크 요청을 보내고 응답을 받을 수 있도록 해주는 매서드이다.

fetch() 함수는 첫번째 인자로 URL, 두번째 인자로 옵션 객체를 받고, Promise 타입의 객체를 반환한다.

 

// get 요청
fetch("http://localhost:3000/user/newMember@naver.com")
  .then((response) => response.json())
  .then((data) => console.log(data));
  
// post 요청
fetch("http://localhost:3000/user", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    userEmail: "test@test",
    password: "test",
    nickname: "test",
  }),
})
  .then((response) => response.json())
  .then((data) => console.log(data))

 

then 대신 async, await을 더많이 사용한다.

async function postData() {
  try {
    const response = await fetch("http://localhost:3000/user", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        userEmail: "test@test",
        password: "test",
        nickname: "test",
      }),
    });
    
    // HTTP 응답이 성공적으로 이루어진 경우에만 처리
    if (response.ok) {
      const data = await response.json();
      console.log(data);
    } else {
      throw new Error('Network response was not ok.');
    }
  } catch (error) {
    console.error('There was a problem with the fetch operation:', error);
  }
}

 

async, await을 사용해서 위 코드처럼 사용할 수 있다.

 

CORS

CORS란 Cross-Origin Resource Sharing (교차 출처 리소스 공유)이다. 출처(Origin)가 교차(Cross)한다는것이 무슨 뜻일까?

 

Origin이란 URL에서 도메인 뿐만아니라 프로토콜과 포트까지 포하는 개념이다

즉 출처가 교차한다는것은 리소스를 주고 받으려는 두 출처가 서로 다르다는 뜻이다. 

 

브라우저는 기본적으로 SOP를 따르고 있다. SOP는 같은 출처(Origin)에서만 리소스를 공유할 수 있다는 규칙이다.

CORS는 반대로 서로 출처가 다르더라도 리소스 요청, 응답을 허용하는 규칙이다.

 

Express 서버를 3000번 포트( http://localhost:3000 ), React 서버를 3001번 ( http://localhost:3001 ) 포트로 열었다.

 

두서버의 Origin 값이 다르기 때문에 (포트번호가 다르다) 프런트 서버에서 fetch를 이용해 express 서버의 api를 호출하면 CORS 에러가 발생한다.

 

따라서 Express에서 CORS 설정을 해야한다.

 

NPM CORS

https://www.npmjs.com/package/cors

 

cors

Node.js CORS middleware. Latest version: 2.8.5, last published: 5 years ago. Start using cors in your project by running `npm i cors`. There are 14679 other projects in the npm registry using cors.

www.npmjs.com

 

마찬가지도 NPM에서 CORS 모듈을 다운받아서 사용하자.

npm install cors
npm install --save @types/cors

 

가장 기본적으로 모든 요청에 대해 CORS 를 허용하는 코드는 아래와 같다.

var express = require('express')
var cors = require('cors')
var app = express()
 
app.use(cors())
 
app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})
 
app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

 

특정 접근 경로에 대해서만 허용하는 코드는 아래와 같다.

var express = require('express')
var cors = require('cors')
var app = express()
 
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})
 
app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

 

일단 모든 요청에 대한 CORS를 허용했다.

 

fetch() 함수를 이용해서 user 정보를 요청하고 데이터를 받아서 출력하자.

'use client'
import React from 'react';
import {useState, useEffect} from 'react';
import {user} from '../types/user'

export default function UserInfo(){
    const [user,setUser] = useState<user>();
    useEffect(()=>{
            async function getUser(){
                try{
                    const response = await fetch("http://localhost:3000/user/newMember@naver.com");
                    if(response.ok){
                        const data = await response.json();
                        // 오류 발생 -> setUser(data);
                        setUser(data.data);
                        console.log('data.data',data.data);
                    }else {
                        throw new Error('Network response was not ok.');
                    }
                } catch (error) {
                    console.error('There was a problem with the fetch operation:', error);
                }
            }
        getUser();
    },[])

    return (
        <div>
            <p>Email: {user && user.userEmail}</p>
            <p>nickname: {user && user.nickname}</p>
            <p>joinDate: {user && user.joinDate}</p>
        </div>
    );
}

 

useEffect는 async 함수를 사용할 수 없기 때문에 내부에서 함수를 선언하고 사용해야한다.

 

 

data 구조가 위와 같아서 setUser(data.data)가 아닌 setUser(data)로 작성했더니 오류가 발생했었다.

 

잘 출력이 된다.

'Express, Next.js > Next.js, React' 카테고리의 다른 글

[React] Suspense, Error boundary 란?  (0) 2024.05.08
[React] useState, useEffect, useRef 정리  (0) 2024.04.19
[React] React 시작하기  (0) 2024.04.16

댓글