2020.07.04(토) Self-studying on weekend

Park, Jinyong·2020년 7월 4일
0

Today I Learned

http 모듈을 실습했다. HTTP Transaction

요청 받은 데이터를 그대로 응답하는 서버

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!'

methods

request.on()
request.on('data', (chunk) => {
  // data 이벤트 핸들러
  // chunk는 Buffer 객체이다.
});

request.on('end' () => {
  // end 이벤트 핸들러
});
response.writeHead(statusCode[, header])
// statusCode와 headers 설정
response.writeHead(200, {
  'access-control-allow-origin': '*'
});

// 아래와 같다.
response.statusCode = 200;
response.setHeader('access-control-allow-origin', '*');
response.end(chunk)
response.end(body); // 데이터를 전달한다.

CORS

CORS로 인해 same-origin 뿐만 아니라 cross-origin의 자원에도 접근할 수 있다.

요청이 simple request의 조건에 부합하지 않는다면 preflight request 방식으로 요청한다. simple request는 본 요청 한 번, 응답 한 번으로 연결이 종료된다. preflight request는 이름 그대로 예비 요청(OPTIONS 메서드)과 본 요청이 나뉘어 전송된다.

OPTIONS 메서드를 먼저 요청하고 200 응답이 확인되면 본 요청을 전송한다.

CORS 요청에 포함된 헤더

Access-Control-Allow-Origin
Access-Control-Allow-Origin: <origin> | *

지정된 도메인으로부터의 요청만 허용한다. 모든 도메인으로부터의 서버 리소스 접근을 허용하려면 *로 지정한다.

Access-Control-Allow-Methods
Access-Control-Allow-Methods: <method> |, <method> | *

본 요청에서 어떤 method를 허용할 지 지정한다.

Access-Control-Allow-headers
Access-Control-Allow-headers: <field-name> |, <field-name>| *

본 요청에서 사용할 수 있는 HTTP headers를 지정한다.

Access-Control-Allow-Credentials
Access-Control-Allow-Credentials: true | false

true일 경우, 요청 시 credential 요청을 보낼 수 있다. Access-Control-Allow-Origin*을 지정하면 안된다.(에러 발생)

Access-Control-Max-Age
Access-Control-Max-Age: <delta-seconds>

preflight request 결과가 캐쉬에 얼마의 시간 동안 남아있을지 지정한다.

curl을 이용해 데이터 요청하기

$ 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 메시지까지 확인할 수 있어서 엄청 유용했다. 역시는 역시다.

남은 주말 동안 밀린 강의 마저 보고 전에 배웠던 내용들을 정리하는 시간으로 해야겠다.

0개의 댓글