본문 바로가기

공부정리

CORS 와 OPTIONS 와 node.js 서버 구축에 대해서..

세가지 요소를 연결지어서 영어소문자를 서버에 전달하면 대문자로 ...

대문자를 서버에 전달하면 소문자로 리턴하는 작업을 해볼려고 한다. 하지만 그전에.!!! 밑의 그림을 좀 더 살펴보고 해보자

Prefilight 와 Main request가 있다.. 

client에서 보내는 데이터들이 있는데 도메인 주소 , 접근 메소드 방식 , 접근 리퀘스트 헤더 등이 있다.

이러한 데이터를 가지고 server에서는 응답을 하는데 맨 첫번째 줄에 보면 HTTP/1.1 200 OK라는것이 보인다.

200이라는 것 이것이 바로 HTTP 상태코드라는 것이다. 그 종류를 간단히 요약하자면 다음과 같다.

  • 1xx (정보): 요청을 받았으며 프로세스를 계속한다
  • 2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
  • 3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
  • 4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
  • 5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다

2xx 번호이므로 성공이라는 상태를 클라이언트에 보내게 되고

주요 요청을 다시 클라이언트에서 서버로 보내게 된다.

서버에서 다시 클라이언트에서 보내는 데이터를 가지고 필터를 거친뒤에 HTTP 상태와 결과를 보내게 된다.

이 부분을 정확하게 이해하지 못하면 앞에서 말한 것들을 짤때 상당히 애를 먹게된다.

Readme에 보시면

- 서버는 POST 요청에 대한 응답을 줄 수 있어야 합니다.

- /lower url 로 온 post 요청은 문자열을 소문자로 만들어서 응답 하여야 합니다.

- /upper url 로 온 post 요청은 문자열을 대문자로 만들어서 응답 하여야 합니다.

- 서버는 POST 요청 이외에는 잘못된 요청임을 클라이언트에 알려줄 수 있어야 합니다.

- 브라우저 보안 이슈로 인해 발생하는 OPTIONS method를 처리할 수 있어야 합니다. 

 

브라우저 보안 이슈로 인해 발생하는 OPTIONS 몌소드를 처리하는 것....

OPTIONS 몌소드일 경우를  나타내면.. 이렇게된다.

1
2
3
4
5
6
7
 //메소드가 옵션일 경우...
 if(method==="OPTIONS"){
    //url upper이나 lower 일때 가능하도록
    response.writeHead(204, headers);
    response.end();
 }
 
cs

response.writeHead(204,headers) ;
204 HTTP 상태를 보내고 headers 헤더 셋팅...

1
2
3
4
5
6
const header = {
  'access-control-allow-origin''*',
  'access-control-allow-methods''GET, POST  PUT, DELETE, OPTIONS',
  'access-control-allow-headers''content-type, accept',
  'access-control-max-age'10
};
cs

헤더에 들어가는 몇 가지 내용들은 정리해보자..

access-control-allow-origin :  모든 도매인(*)을 허용한다.

access-control-allow-methods : 메소드는 GET , POST , PUT, DELETE, OPTIONS만 허용 한다.

access-control-allow-headers : 헤더에는 content-type 과 accept만 쓸 수 있다.

access-control-max-age : preflight request는 10초까지 허용된다.

 

response.end();에 대해서... 

일단 응답 바디 전송하는 법을 이야기 하자면...

response 객체는 WritableStream이므로 클라이언트로 보내는 응답 바디는 일반적인 스트림 메서드를 사용해서 작성합니다.

1
2
3
4
5
6
response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();
cs

스트림의 end 함수에 스트림에 보낼 데이터의 마지막 비트를 선택적으로 전달할 수 있으므로 위의 예제는 다음과 같이 간단하게 작성할 수 있습니다.

1
response.end('<html><body><h1>Hello, World!</h1></body></html>');
cs

response.write(element)로 작성을 해서 출력을 마지막에 response.end()로 해도 되고

response.end(element)에 다 넣어서 한번에 출력을 해도 된다는 이야기이다.

 

그럼 요청 바디에 대해서 이야기를 해보자

바디데이터를 받는 것은 어떻게 구현 하면 될지 일단 예시 코드를 보여주겠다.

1
2
3
4
5
6
7
let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // 여기서 `body`에 전체 요청 바디가 문자열로 담겨있습니다.
});
cs

핸들러에 전달된 request 객체는 ReadableStream 인터페이스를 구현하고 있습니다.
이 스트림에 이벤트 리스너를 등록하거나 다른 스트림에 파이프로 연결할 수 있습니다.
스트림의 'data'와 'end' 이벤트에 이벤트 리스너를 등록해서 데이터를 받을 수 있습니다.
 'data' 이벤트에서 발생시킨 청크(chunk)는 Buffer입니다. ( 이 부분이 중요하다)
이 청크가 문자열 데이터라는 것을 알고 있다면 이 데이터를 배열에 수집한 다음 'end' 이벤트에서 이어 붙인 다음 문자열로 만드는 것이 가장 좋습니다.
그래서 toString을 사용해서 타입을 변환시켜서 준다...

오류에 대해서 

1
2
3
4
request.on('error', (err) => {
  // 여기서 `stderr`에 오류 메시지와 스택 트레이스를 출력합니다.
  console.error(err.stack);
});
cs

오류를 발생시키는 것을 적어야 하는 이유는 잘못하면 계속 구동되어야하는 서버를 종료시킬 수도 있기 떄문이다. 예를들어서 은행 입출금 시스템 같은 경우 서버가 꺼진다면 어떻게 되겠는가..?? 상상만 해도 끔찍할것이다.

 

그러면 코드 구현을 하는 건 어떻게 해야할까?..

1. OPTION 일 경우 서버와 클라이언트 왓다갔다 (위에 있음)

2. POST 일 경우에 url 부분이 /lower 일 경우와 /upper 일 경우에만 요청한 바디에 대한 값을 가져와서 lower에 대한 것과 upper 일 경우에 대해서 필터를 거쳐서 스트림에 보낸다.

3. 나머지 경우에 대해서는 잘못된 요청이라는 메세지를 보낸다.