공공데이터 api를 사용하려 했지만 CORS이슈발생, 이유는 클라이언트에서 바로 요청 접근해서 브라우저 관련된 정책이기 때문에 위반된다고 판단하는것이다.
따라서 따로 서버에서 서버로 리소스를 요청하면 CORS 정책을 위반하지 않고 정상적으로 응답한다고 한다.
이를위해 express사용하여 프록시 서버(백엔드서버)를 구축하기로했다.
프록시 서버란?
클라이언트가 자신을 거쳐 다른 네트워크에 접속할 수 있도록 중간에서 대리해주는 서버. 서버와 클라이언트 사이에서 대리로 통신을 수행해주는 것을 프록시라고 하고 그 기능을 하는 서버를 프록시 서버라고 부르게 되는 것 이다.
CORS란?
Cross-Origin Resource Sharing 약자로 서로 다른 출처(Origin)간에 리소스를 전달하는 방식을 제어하는 체제
보안상의 이유로 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한한다. -> (궁금한점: 서버나 클라이언트에서 http를 요청시 똑같은 js 파일에서 요청을 하는데 어떻게 구분하여 제한하는지?? 스크립트라하면 결국 js코드가 DOM으로 브라우저 상에 보여지는 소스인지 아닌지 판별하나?)
예를들어 XMLHttpRequest와 Fetch API는 동일 출처 정책을 따른다. 이 API를 사용하는 웹 어플리케이션은 자신의 출처와 동일한 리소스만 불러올수있고 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.
출처가 다른 경우란? Internet Explorer 예외사항
1. 프로토콜이 다른경우 (http, https가 동일해야한다. http->https는 가능하지만 반대의 경우 에러)
2. 도메인이 다른경우 요청 (www.naver.com - www.daum.net)
3. 포트번호가 다른경우 (www.naver.com:3000 - www.naver.com:8080)
* 경로는 상관없다 ex) www.naver.com - www.naver.com/webtoon/list.nhn?titleId=703846&weekday
그래서 CORS 해결방법은 무엇인가? ❓
1. 요청시 JSONP를 활용한다. -> get 요청만 가능...
2. 미들웨어 CORS 추가. -> 서버설정을 직접할 수 가 없다...
3. 백엔드 서버를 거친다. -> 개발자가 구축하면 되서 확실하다.!
4. 프록시 서버 구축 -> 실무에서 많이 사용한다고 한다.
맨처음 에러사진처럼 프론트단 클라이언트에서 axios 요청을하면 CORS 에러가 났는데, node.js로
express 사용해서 똑같은 js 파일인데 요청코드도 똑같은데 에러가 안나는게 신기하다.
서버를 열기위해 express 사용하였고 오픈api를 요청하기위해 axios 를 썼다.
중요한건 리액트 CRA를 통해 만들었을때는 import .. from 을 사용했지만, 그게 아니라면 모듈 과 webpack 번들화가 안되어서 못쓰는거같다.
따라서 위에서처럼 require()을 써야한다.
response.json()
그리고나서 express을 이용하여 get요청으로 '/' 경로에서 currentPut 함수를 실행하게하여 공공데이터를 불러오고 그 값을 response에 담아주었다. 이때 xml 파일형태로 가져왔기때문에 json() 내장 함수가 있는데, res.json 메서드 사용 시 HTTP 응답 body 텍스트를 JSON 형식으로 바꾼 프로미스를 반환한다. .json()은 parameter를 JSON으로 변환해서 body(객체)에 저장하고 응답 헤더를 application/json으로 세팅한다. 만약 json 을 쓰지않으면 받아오는 데이터가 없었다.
그리고 setHeadet부분에서 CORS 를 "*" 를 사용해서 클라이언트 로컬포트에서 요청할수있게 해주었다. 만약 저부분을 없애게되면
위와같이 에러가 난다. 그래서 "*"을 통해 어디서든 요청을 할수있게 한건데
이렇게 localhost:3000부분만 허용하도록 할수도있다.
이렇게해서 console.log 찍어보면 우리가 원하는 데이터가 data에 담겨서 오는걸 알수있다.
res.send()와 res.json() 차이?
사실 res.send()와 res.json()은 별반 다를바 없다. 하지만 다음과같은 차이는 있다
- res.send()는 send에 전해진 argument에 따라서 Content-type이 자동적으로 만들어진다. 이게 기본이다.
- res.json()은 json이 아닌 것도 json 형식으로 바꾸어서 보내준다. 즉 content-type 헤더를 application/JSON으로 고정한다. 그런데 결국 res.json()도 마지막에 res.send()를 호출한다.
- res.end()는 보내줄 아무 데이터도 없는데 response를 끝내고 싶을 때 사용한다.
ex) res.status(400).end();
고려,시도해볼것 CheckList
- 현재 서버나 클라이언트가 로컬로 되어있는데 http 나 https 로 서버 배포시에도 코드그대로 쓰면 openapi를 사용할수있는지 체크해야한다
'TIL' 카테고리의 다른 글
[TIL] 참조타입!! (0) | 2022.02.26 |
---|---|
[TIL] 넘치도록 해야할것들?! (2) | 2022.02.23 |
[TIL] Typescript 타입스크립트 (0) | 2022.02.20 |
[TIL] 모의면접 (0) | 2022.02.19 |
[TIL] node.js 이용 서버구축 하기 (0) | 2022.02.18 |