CORS(Cross-Origin Resource Sharing) 처리방안
1. 처리방안
1안) 서버 측에서 Access-Control-Allow-Origin 헤더를 설정하여 클라이언트의 요청 출처를 허용하는 것.
2안) 프록시 서버를 사용하거나, 브라우저 확장 프로그램을 활용하는 방법.
openapi 호출할 때 CORS가 발생하여, 1안으로는 해결할 수 없어서 2안으로 진행함.
2. 구현절차
2.1 proxy module 설치
npm install http-proxy-middleware
2.2 proxy module 설정
setupProxy.js 파일을 생성하고, 설정한다.
- 호출 하려는 url: https://apihub.kma.go.kr/api/typ02/openApi/VilageFcstMsgService/getLandFcst?pageNo=1&numOfRows=10&dataType=JSON®Id=11B20601&authKey=인증키
- proxy로 호출하는 url: http://localhost:3001/proxy/api/typ02/openApi/VilageFcstMsgService/getLandFcst?pageNo=1&numOfRows=10&dataType=JSON®Id=11B20601&authKey=인증키
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/proxy',
createProxyMiddleware({
changeOrigin: true,
})
);
};
매핑된 /proxy는 client에서 proxy 구분으로 사용될 뿐, 실제서버에서는 url에 들어가지 않음. (react 버전 19.2.0 기준)
2.3. proxy url로 호출
import React, { useState } from 'react';
import './App.css';
function App() {
// const [temp, setTemp] = useState("");
const [isReady, setIsReady] = useState(false);
const [data, setData] = useState(null);
const params = new URLSearchParams({
pageNo: 1,
numOfRows: 10,
dataType: 'JSON',
regId: '11B20601', // 수원지역
authKey: '인증키'
});
React.useEffect(() => {
fetch(`proxy/api/typ02/openApi/VilageFcstMsgService/getLandFcst?${params.toString()}`)
.then(response => response.json())
.then(data => {
setData(data.response.body.items.item);
setIsReady(true);
})
.catch(error => console.error('Error fetching data:', error));
}, []);
if(isReady) {
return (
<div className="App">
<h1>Weather Data</h1>
<table border="1">
<thead>
<tr>
<th>Announce Time</th>
<th>지역코드</th>
<th>발효번호(발표시간기준)</th>
<th>날씨</th>
<th>강수확률</th>
<th>풍향1</th>
<th>풍향2</th>
</tr>
</thead>
<tbody>
{data && data.map((item, index) => (
<tr key={index}>
<td>{item.announceTime}</td>
<td>{item.regId}</td>
<td>{item.numEf}</td>
<td>{item.wf}</td>
<td>{item.rnSt}</td>
<td>{item.wd1}</td>
<td>{item.wd2}</td>
</tr>
))}
</tbody>
</table>
</div>
);
} else {
return (
<div className="App">
Loading...
</div>
);
}
}
export default App;
결과
end.