const http = require('http'); // http 모듈
const corsHeaders = { // cors를 위한 헤더
'access-control-allow-origin': '*', // 모든 도메인에서 허용
'access-control-allow-method': 'POST', // POST 요청만 허용
'access-control-allow-headers': 'content-type', // content-type 지정 가능
};
http.createServer((request, response) => { // http 요청이 오면 실행될 콜백함수
let body = ''; // 전송할 데이터
request.on('data', (chunk) => { // data를 수신했을 때 이벤트 처리
body = chunk.toString();
}).on('end', () => { // 요청 종료 이벤트
response.writeHead(200, corsHeaders) // header 작성: OPTIONS, POST 둘 다 동일
response.end(body); // 클라이언트 측으로 데이터 전달
});
}).listen(8080); // 8080 port => http://localhost:8080
fetch('http://localhost:8080', {
method: 'POST',
body: JSON.stringify('Hello, world!'),
headers: {
'content-type': 'text/json'
}
}).then(res => res.json())
.then(console.log)
// 'Hello, world!'
request.on('data', (chunk) => {
// data 이벤트 핸들러
// chunk는 Buffer 객체이다.
});
request.on('end' () => {
// end 이벤트 핸들러
});
// statusCode와 headers 설정
response.writeHead(200, {
'access-control-allow-origin': '*'
});
// 아래와 같다.
response.statusCode = 200;
response.setHeader('access-control-allow-origin', '*');
response.end(body); // 데이터를 전달한다.
CORS로 인해 same-origin 뿐만 아니라 cross-origin의 자원에도 접근할 수 있다.
요청이 simple request의 조건에 부합하지 않는다면 preflight request 방식으로 요청한다. simple request는 본 요청 한 번, 응답 한 번으로 연결이 종료된다. preflight request는 이름 그대로 예비 요청(OPTIONS 메서드)과 본 요청이 나뉘어 전송된다.
OPTIONS 메서드를 먼저 요청하고 200 응답이 확인되면 본 요청을 전송한다.
Access-Control-Allow-Origin: <origin> | *
지정된 도메인으로부터의 요청만 허용한다. 모든 도메인으로부터의 서버 리소스 접근을 허용하려면 *
로 지정한다.
Access-Control-Allow-Methods: <method> |, <method> | *
본 요청에서 어떤 method를 허용할 지 지정한다.
Access-Control-Allow-headers: <field-name> |, <field-name>| *
본 요청에서 사용할 수 있는 HTTP headers를 지정한다.
Access-Control-Allow-Credentials: true | false
true
일 경우, 요청 시 credential 요청을 보낼 수 있다. Access-Control-Allow-Origin
에 *
을 지정하면 안된다.(에러 발생)
Access-Control-Max-Age: <delta-seconds>
preflight request 결과가 캐쉬에 얼마의 시간 동안 남아있을지 지정한다.
$ curl -X OPTIONS http://localhost:8080 -i
HTTP/1.1 200 OK
access-control-allow-origin: *
access-control-allow-method: POST
access-control-allow-headers: content-type
Date: Sat, 04 Jul 2020 06:32:41 GMT
Connection: keep-alive
Transfer-Encoding: chunked
$ curl -X POST -d 'Hello, world!' http://localhost:8080 -i
HTTP/1.1 200 OK
access-control-allow-origin: *
access-control-allow-method: POST
access-control-allow-headers: content-type
Date: Sat, 04 Jul 2020 06:33:49 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Hello, world!
오늘은 http 모듈을 사용하여 서버를 생성하고, 요청과 응답을 처리하는 법을 알아보았다. 어제는 OPTIONS
메서드 요청이 올 경우에 따로 처리를 해줘야하는 줄 알았는데, 그냥 preflight 요청을 위한 헤더를 설정해주면 알아서 예비 요청과 본 요청에 응답을 했다. 브라우저가 알아서 처리해주는 덕분인 것으로 보인다.
크롬에서 OPTIONS 요청을 따로 확인할 수 없었던 문제로 골치 아팠는데, curl
명령어로 CLI 환경에서 별도로 확인할 수 있고 HTTP 메시지까지 확인할 수 있어서 엄청 유용했다. 역시는 역시다.
남은 주말 동안 밀린 강의 마저 보고 전에 배웠던 내용들을 정리하는 시간으로 해야겠다.