공시정보 Dart 에서 제공하는 OpenAPI로 공시정보 페이지 만들기 + 필터링까지
dart : https://opendart.fss.or.kr/intro/main.do
CORS 에러
Access to XMLHttpRequest at 'https://opendart.fss.or.kr/api/list.json?crtfc_key=비밀&corp_code=비밀&bgn_de=비밀&end_de=비밀&page_count=10&page_no=1' from origin 'http://localhost:1004' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
이게 뭐야..하면서 열심히 찾아봤었는데 이 블로그가 아주 도움이 됐다 참고
확인해보니 api로 인한 cors 에러는 우회하는 게 필요하다는데 프로젝트 라이브러리에 설치하고 어쩌구라고 해서 괜히 했다가 망가질까봐 고민하고 있던 차~ 백엔드에서 우회 링크를 주셨다.
로컬, 실섭 둘 다 안되고 있었는데 우선 로컬만 해결 하면 되니까 https://cors-anywhere.herokuapp.com 를 링크 앞에 붙혀서 데모 버전으로 우선 작업을 시작했다.
시간이 지나면 자동으로 임시 엑세스 권한이 사라져서 작업 전에 여기서 임시 엑세스 요청을 하면 된다.
1) 처음에 백엔드에서 받은 코드
로컬/서버일 때의 조건으로 나눠져 연결되는 url이 다르게 들어감.
const openDartApi = () => {
const localUrl = "https://cors-anywhere.herokuapp.com/https://opendart.fss.or.kr/api/list.json?crtfc_key=비밀&corp_code=비밀&bgn_de=비밀&end_de=비밀&corp_cls=Y&page_no=1&page_count=15";
const serverUrl = "https://opendart.fss.or.kr/api/list.json?crtfc_key=비밀&corp_code=비밀&bgn_de=비밀&end_de=비밀&corp_cls=Y&page_no=1&page_count=15&pblntf_ty=A";
axios
.get(location.host.includes('localhost') ? localUrl : serverUrl)
.then((response) => {
const object = response.data;
if(object.message === "정상") { // 화면에 뿌릴때 innerHtml 쓰지 않기.
console.log(object.page_no); // 페이지네이션 class에 on을 줘서 선택된거.
// 넘버링 : (page_no -1) * page_count + list[i] + 1
console.log(object);
console.log(object.list[0].report_nm);
} else {
alert("비정상적인 접근입니다.");
location.href = "/";
}
})
.catch((error) => {
console.log(`error ${error}`);
})
.finally(() => {
console.log("===opendart end===");
});
}
2) 작업하면서 변수가 유동적으로 변경이 필요해 js로 수정
bgn_de, end_de 등과 같이 사용자의 선택에 따라 값이 바뀌어 다시 검색 되어야 하는 부분이 있기 때문.
// API 요청에 필요한 파라미터
const crtfc_key = "비밀";
const corp_code = "비밀";
const bgn_de = startDate;
const end_de = endDate;
const page_count = itemsPerPage;
const page_no = page || 1;
// API 요청 URL
const localUrl = `https://cors-anywhere.herokuapp.com/https://opendart.fss.or.kr/api/list.json?crtfc_key=${crtfc_key}&corp_code=${corp_code}&bgn_de=${bgn_de}&end_de=${end_de}&page_count=${page_count}&page_no=${page_no}${pblntf_ty}`;
const serverUrl = `https://opendart.fss.or.kr/api/list.json?crtfc_key=${crtfc_key}&corp_code=${corp_code}&bgn_de=${bgn_de}&end_de=${end_de}&page_count=${page_count}&page_no=${page_no}${pblntf_ty}`;
console.log(pblntf_ty, apiUrl)
// Axios를 사용하여 API 요청
axios
.get(location.host.includes('localhost') || location.host === '192.168.0.97:1004' ? localUrl : serverUrl)
.then((response) => {
const object = response.data;
if (object.message === "정상") {
// 정상적인 응답인 경우 테이블과 페이지네이션을 업데이트
displayTable(object.list, object.total_count);
displayPagination(object.total_page);
} else {
// 정상적이지 않은 경우 경고 메시지 출력 및 홈페이지로 이동
if (object.message !== "조회된 데이타가 없습니다.") {
alert("비정상적인 접근입니다.");
location.href = "/disclosure_info4";
} else {
// 검색 결과가 없는 경우
displayTable([], 0);
displayPagination(0);
}
}
})
.catch((error) => {
console.log(`error ${error}`);
});
}
이런 식으로 유동적으로 변경 되어야 하는 부분들을 변수에 담아 파라미터가 바뀔 수 있게 수정해서 사용하였다. 작업이 완료된 페이지라 if안에 다른 함수들이 있지만 이건 무시하고,
공식 홈페이지에서 데이터를 불러오는 파라미터, 에러메세지 등을 알 수 있어 그것에 맞게
조건을 넣고 필요한 정보들을 가져오면서 작업했다.
3) 현재
보안을 생각한 방법으로 변경
현재는 실서버 SSH 설치로 인한 보안으로 (임시 엑세스 코드를 넣을 수도 없고 보안도 약해지고 주기적으로 눌러야하기 때문) json으로 api 받아온 후 바로 사용이 불가하여 내부적으로 데이터를 프로젝트쪽 컴포넌트로 한번 더 받아온 뒤 사용 가능해졌다 (서버쪽이라 백엔드에 요청 필요)
이렇게 하니 우회 링크를 사용하지 않아도 로컬, 실섭에서 모두 정상 노출 되는 것으로 해결 ~
데이터를 가져오는 파라미터를 활용해 검색 필터 기능을 추가해두었는데,
이건 다음 게시글에서 한번에 다뤄야겠다. 오케이 대음.