참고 블로그1 : Inpa Dev
🌐 악명 높은 CORS 개념 & 해결법 - 정리 끝판왕 👏
악명 높은 CORS 에러 메세지 웹 개발을 하다보면 반드시 마주치는 멍멍 같은 에러가 바로 CORS 이다. 웹 개발의 신입 신고식이라고 할 정도로, CORS는 누구나 한 번 정도는 겪게 된다고 해도 과언이
inpa.tistory.com
참고 블로그 2: 호두파파
(React) React App에서 CORS 이슈 해결하기
CORS가 무엇인지, CORS 이슈를 어떻게 극복할지 알아보자
velog.io
그리고 gpt..
웹 개발자라면 한 번 쯤 겪는다는,, CORS 에러,, 이렇게 겪어보다,,
공부 하는대로 정보 추가 할 예정 --> 추가 완료
CORS 에러 란?
교차 출처 리소스 공유 Cross-Origin Resource Sharing
브라우저가 다른 도메인, 프로토콜 또는 포트에서 리소스를 요청할 때 보안상의 이유로 제한하는 기능을 말한다. 즉 브라우저가 자신의 출처가 아닌 다른 어떤 출처(도메인, 프로토콜, 포트)로부터 자원을 로딩하는 것을 허용하도록 서버가 허가 해주는 매커니즘을 말한다.
출처 ORIGIN | |
동일한 스킴(http)와 호스트 이름(example.com)을 갖고 있음 출처는 동일합니다. http://example.com/app1/index.html http://example.com/app2/index.html 다른 파일 경로는 중요하지 않습니다. |
서버는 기본적으로 포트 80을 통해 HTTP 콘텐츠를 전달 출처는 동일합니다. http://example.com:80 http://example.com 서로 다른 포트를 사용하기 때문에 동일한 출처가 아닙니다. http://example.com http://example.com:8080 |
서로 다른 스킴을 사용 동일한 출처가 아닙니다. http://example.com/app1 https://example.com/app2 |
서로 다른 호스트 이름을 사용 동일한 출처가 아닙니다. http://example.com http://www.example.com http://myapp.example.com |
해결방법
1. 크롬 확장 프로그램 사용하기
2. 프록시 서버 이용하기
3. 서버에서 Access-Control-Allow-Origin 헤더 세팅하기
오류를 보면 "No 'Access-Control-Allow-Origin' header is present on the requested resource." 라고 쓰여 있는 걸 볼 수 있다.
3-1. 백엔드 프록시 설정 (개발 환경에서)
사용한 API는 네이버맵 API 다. (Geocoding 사용)
pakage.json 에 proxy 를 추가하여 넣는다.
이 proxy 는 Origin에서 API 요청이 나가는 것을 막고, react 개발 서버가 대신 요청을 전송하게 된다.
{* 변경 전 *}
const geo = `https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=${address}`;
{* 변경 후 *}
const geo = `/map-geocode/v2/geocode?query=${address}`;
변경 전 오류
변경 후 오류
CORS 에러가 해결된 것을 볼 수 있다.
(gpt가 알려준 건 이 방법인데, 아직 배포는 못 해서 이게 되는지는 모르겠다.)
3-2. CORS 문제를 백엔드에서 해결 (배포 환경에서)
프로젝트와 같은 선상에 proxy 관련 디렉토리를 만든 후 디렉토리로 이동
package.json 생성 후 express, cors 모듈 설치한다.(Node.js 프로젝트 초기화 및 패키지 설치)
npm init -y
npm install express cors node-fetch
필요한 종속성을 package.json에 추가한다. (여기서 nodemon 도 같이 설정해 놓으면 좋을 것 같다)
{
"scripts": {
"start": "node server.js" // server.js가 서버 파일이라면
}
}
.env 파일 만들기
React 파일에서 만들었던 .env 파일을 가져오면 되는데, 여기선 이름만 'REACR_APP_'을 제거하면 된다.
아래는 내 예시이다.
API_Naver_ID = []
API_Naver_Key = []
CLIENT_URL = http://localhost:[]
(선택) CommonJS >> ES 모듈 변경
const express = require('express');
const fetch = require('node-fetch');
const cors = require('cors');
// .env 파일에서 환경 변수를 불러오기
require('dotenv').config();
import express from 'express';
import cors from 'cors';
import fetch from 'node-fetch';
import dotenv from 'dotenv';
dotenv.config();
const app = express();
const PORT = 4000;
주로 서버의 port 는 5000 이라고한다. 하지만, 나는 5000 port 에서 따로 사용되는 것이 있어 4000으로 변경했다.
만약 포트 충돌이 일어난다면 아래 코드로 확인하고 삭제하면 되는데, 되도록이면 다른 포트를 파는 걸 추천한다.
// 확인
lsof -i :[포트 번호]
// 삭제
kill -9 [PID 번호]
// app.use(cors({ origin: '*' })); // 모든 출처에서 오는 요청을 허용 (보안상 좋지 않음)
// CORS 설정을 더 제한적으로 변경
app.use(cors({ origin: process.env.CLIENT_URL || 'http://localhost:3000' }));
// 루트 경로 핸들러
app.get('/', (req, res) => {
res.send('Welcome to the API server'); // 응답 추가
});
// 네이버 API 프록시
app.get('/api/naver', async (req, res) => {
const address = req.query.query;
res.send(address);
const geoID = process.env.API_Naver_ID;
const geoKey = process.env.API_Naver_KEY;
const encodedAddress = encodeURIComponent(address);
const response = await fetch(https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=${encodedAddress}, {
headers: {
'X-NCP-APIGW-API-KEY-ID': geoID,
'X-NCP-APIGW-API-KEY': geoKey,
},
});
const data = await response.json();
res.json(data);
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
'개인 공부 > 프론트' 카테고리의 다른 글
[typescript] 땅콩코딩 타입스크립트 강좌 - 1 (0) | 2024.11.13 |
---|---|
[React] 공공데이터 기상청 API (정보보관용) (0) | 2024.10.22 |
[React] OpenWeatherMap 날씨 api 연결 (0) | 2024.10.14 |
[React] 기본 브라우저 모든 css 제거하기 (0) | 2024.10.12 |