Node.js 및 React 애플리케이션에서 CORS 오류를 해결하는 방법
프로젝트 설정
다음 명령을 사용하여 React 프로젝트를 생성해 보겠습니다.
npx create-react-app react-cors
이제 다음 코드를 사용하여
App.js
를 업데이트합니다.import { useEffect, useState } from "react"
import "./App.css"
function App() {
const [message, setMessage] = useState("")
useEffect(() => {
fetch("https://nodejs-using-github.herokuapp.com/")
.then(response => response.json())
.then(data => {
setMessage(data.message)
})
.catch(err => console.log(err))
}, [])
return <div className="App">{message ? message : "Loading.."}</div>
}
export default App
여기에는
message
라는 로컬 상태가 있으며 이를 사용자에게 보여줍니다. 메시지가 비어 있으면 로드 텍스트와 함께 표시합니다. 컴포넌트가 마운트되면(useEffect) API 엔드포인트를 호출하고 메시지를 가져옵니다.이제 이것을 실행하고 작동하는지 봅시다:
npm start
"Loading.."텍스트만 표시되고 메시지가 로드되지 않는 것을 볼 수 있습니다. 페이지를 검사하고 콘솔을 보면 다음 오류가 표시됩니다.
Access to fetch at 'https://nodejs-using-github.herokuapp.com/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
다음 섹션에서는 CORS가 무엇이고 이 오류를 수정하는 방법을 살펴보겠습니다.
CORS(Cross-Origin Resource Sharing)란 무엇입니까?
CORS는 Cross-Origin Resource Sharing 을 의미하며, 이는 서버가 모든 도메인 요청이 이루어질 수 있는 브라우저를 알려주는 데 도움이 되는 HTTP 헤더 기반 메커니즘입니다(동일한 도메인 제외).
즉, 우리의 경우
https://nodejs-using-github.herokuapp.com/
에서 호스팅되는 Node.js 서버는 http://localhost:3000
에서 요청이 이루어질 수 있음을 브라우저에 알리지 않습니다.이런 일이 발생하면 앞에서 본 것처럼 브라우저에서 오류가 발생합니다.
왜 CORS(Cross-Origin Resource Sharing)인가?
다음 질문은 왜 우리에게 이 메커니즘이 필요한가 하는 것입니다. 은행 계좌나 소셜 미디어 웹사이트에 로그인한 다음 악성 웹사이트를 방문한다고 상상해 보십시오.
이 악성 웹사이트는 백그라운드에서 일부 스크립트를 실행하여 개인 정보를 얻기 위해 은행 또는 소셜 미디어에 대한 API 호출을 할 수 있습니다.
이를 방지하기 위해 브라우저는 악성 웹사이트에서 은행 또는 소셜 미디어 서버에 대한 요청을 할 수 있는지 확인하고 CORS 오류를 발생시킵니다.
따라서 CORS는 신뢰할 수 있는 타사(서로 다른 출처/도메인) 간에 특정 리소스를 공유하기 위해 존재하므로 Cross-Origin Resource Sharing이라는 이름이 있습니다.
Node.js에서 CORS를 구성하는 방법
CORS가 무엇이고 왜 필요한지 명확하게 알고 있으므로 Node.js 애플리케이션에서 CORS를 활성화하는 방법을 살펴보겠습니다.
Node.jscode from this repo를 복제할 수 있습니다. 프로젝트가 복제되면 코드 편집기에서 열고 cors package을 설치합니다.
npm i cors
이제
index.js
를 열고 다음 코드로 업데이트합니다.const express = require("express")
const cors = require("cors")
const app = express()
const port = process.env.PORT || 3000
const whitelist = ["http://localhost:3000"]
const corsOptions = {
origin: function (origin, callback) {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error("Not allowed by CORS"))
}
},
credentials: true,
}
app.use(cors(corsOptions))
app.get("/", (req, res) => {
res.send({ message: "Hello World!" })
})
app.listen(port, () => {
console.log(`Example app listening at Port: ${port}`)
})
여기에서 원본(클라이언트의 도메인)이 화이트리스트에 있는지 확인한 다음 클라이언트에게 요청을 할 수 있음을 알립니다. 목록에 없으면 클라이언트가 이 서버에 CORS 요청을 할 수 없다는 오류가 발생합니다.
The domain should not have any trailing slashes (/)
deploy the changes to Heroku 이것이 작동하는지 확인할 수 있습니다.
이제 페이지를 새로고침하면 메시지를 볼 수 있습니다.
또한
Access-Control-Allow-Origin
라는 응답 헤더가 http://localhost:3000
값으로 추가된 것을 볼 수 있습니다.CORS 도메인을 구성 가능하게 만들기
연결할 클라이언트 원본이 여러 개인 경우 구성 가능하게 하려면 환경 변수를 사용하면 됩니다.
const express = require("express")
const cors = require("cors")
const app = express()
const port = process.env.PORT || 3000
const domainsFromEnv = process.env.CORS_DOMAINS || ""
const whitelist = domainsFromEnv.split(",").map(item => item.trim())
const corsOptions = {
origin: function (origin, callback) {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error("Not allowed by CORS"))
}
},
credentials: true,
}
app.use(cors(corsOptions))
app.get("/", (req, res) => {
res.send({ message: "Hello World!" })
})
app.listen(port, () => {
console.log(`Example app listening at Port: ${port}`)
})
로컬에서 환경 변수 테스트
환경 변수를 로컬에서 테스트하려면
dotenv
라는 패키지를 설치할 수 있습니다.npm i dotenv
이제 도메인이 있는 프로젝트의 루트 디렉터리에
.env
라는 파일을 만듭니다.CORS_DOMAINS = http://localhost:3000, http://localhost:3001, https://example.com
index.js
패키지를 사용하도록 업데이트dotenv
:const express = require("express")
const cors = require("cors")
const app = express()
const port = process.env.PORT || 3000
if (process.env.NODE_ENV !== "production") {
require("dotenv").config()
}
const domainsFromEnv = process.env.CORS_DOMAINS || ""
const whitelist = domainsFromEnv.split(",").map(item => item.trim())
const corsOptions = {
origin: function (origin, callback) {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error("Not allowed by CORS"))
}
},
credentials: true,
}
app.use(cors(corsOptions))
app.get("/", (req, res) => {
res.send({ message: "Hello World!" })
})
app.listen(port, () => {
console.log(`Example app listening at Port: ${port}`)
})
여기서 우리는
.env
파일이 비프로덕션 환경에서만 로드되도록 했습니다. 프로덕션용 .env 파일이 아닌 서버 호스트에 구성을 저장하는 것이 좋습니다.Remember to add
.env*
to the.gitignore
file so that you don't accidentally push them to the repo.
heroku에서 환경 파일 구성
최신 코드를 사용하여 heroku 설정에서 환경 파일을 구성할 수 있습니다.
프로젝트 설정으로 이동하여 "구성 변수 표시"를 클릭합니다. 이제 여기에 키와 값을 제공하고 "추가"를 클릭할 수 있습니다.
추가되면 변경 사항을 푸시하고 변경 사항이 작동하는지 확인할 수 있습니다.
Reference
이 문제에 관하여(Node.js 및 React 애플리케이션에서 CORS 오류를 해결하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/collegewap/how-to-solve-cors-error-in-nodejs-and-react-applications-36k2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)