http 서버에서 헤더를 굳이 설정해주는 이유는?

김철준·2023년 3월 20일
0

node.js

목록 보기
6/6

응답해줄 문서에 대한 헤더를 설정해줘야하는 이유?

브라우저에서 응답받을 문서에 대하여 알아서 인식하는데도 불구하고 http 서버에서 응답보낼 문서에 대한 헤더를 설정해줘야하는 이유가 뭘까요?

다음 코드를 살펴봅시다.

with header

const http = require("http");

const server = http.createServer((req, res) => {

  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
  res.write("<h1>Hello node!</h1>");
  res.end("<p>Hello Server!</p>");
});

server.listen(8080, () => {
  console.log("8080번 포트에서 서버 대기 중...");
});
  • res.wrieHead : 서버에서 클라이언트에게 응답해줄 데이터(body)에 대한 헤더의 내용을 표시할 수 있는 메서드입니다.
    헤더에서는 요청과 응답간에 본문에 대한 부가적인 정보를 전달해주는 역할을 합니다.

  • Content-Type : 서버에서 응답해줄 데이터 타입을 표시할 수 있는 속성입니다.

  • res.write : 본문에 대한 내용을 적을 수 있습니다.

  • res.end : 본문에 대한 내용을 적고 응답을 마무리합니다.

위와 같이 코드를 입력하고 8080포트에서 페이지를 열면 다음과 같이 정상적으로 나타납니다.

하지만 다음과 같이 헤더에 대한 코드를 없애도 정상적으로 나타냅니다.

no header

const http = require("http");

const server = http.createServer((req, res) => {
  // 굳이 writeHead로 html인 것과 charset이 utf-8인 것을 안 알려줘도 html인 것을 인식하는데 왜 쓰는 걸까?
  //   res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
  res.write("<h1>Hello node!</h1>");
  res.end("<p>Hello Server!</p>");
});

server.listen(8080, () => {
  console.log("8080번 포트에서 서버 대기 중...");
});

위 코드와 같이 헤더에서 응답해줄 html 내용에 대한 데이터 타입 종류와 문자 인코딩을 명시해주지않아도 html 내용이 전달됩니다.

헤더에서 명시해주지않았는데 어떻게 전달이 될까요?

브라우저의 헤더 Content-Type 유추 기능(MIME sniffing)

브라우저가 자동으로 이러한 헤더를 유추할 수 있기 때문에, 별도의 헤더 설정이 없어도 제대로 동작합니다.

일반적으로 웹 브라우저들은 HTTP 응답에서 Content-Type 헤더가 누락되었을 때, 다양한 형식의 컨텐츠를 감지하고 자동으로 적절한 Content-Type을 추론하는 기능을 가지고 있습니다. 이 기능을 MIME 스니핑(MIME sniffing) 또는 MIME 타입 추론(MIME type inference)이라고 합니다.

예를 들어, 웹 브라우저는 HTTP 응답에서 HTML 태그를 발견하면 이를 HTML 페이지로 간주합니다. 그리고 HTTP 응답의 Content-Type 헤더가 누락되었다면, 브라우저는 내부적으로 MIME 스니핑을 수행하여 HTML 페이지로 추론합니다.

하지만 이러한 자동 추론 기능은 모든 브라우저에서 동작하지 않을 수 있으며, 예측하지 못하는 결과를 가져올 수도 있습니다. 따라서, Content-Type 헤더를 명시적으로 설정하는 것이 안전하며, 이를 권장합니다. 또한, Content-Type 헤더를 명시적으로 설정하면, 브라우저가 추론한 것과 다른 데이터 타입을 전송해야 하는 경우에도 명확한 데이터 타입을 전송할 수 있습니다.

문자 인코딩 인식 기능

그렇다면 헤더에서 문자 인코딩을 utf-8이라고 해주지 않았음에도 불구하고 본문에서 한글을 보냈을 때 깨지지 않는 이유는 뭘까?

HTTP/1.1 스펙에 따르면, 만약 Content-Type 헤더에서 문자 인코딩을 명시하지 않은 경우, 기본적으로 ISO-8859-1(라틴1) 문자 인코딩이 사용됩니다. 따라서, 한글과 같은 멀티바이트 문자는 ISO-8859-1 인코딩으로 전송될 때 깨질 수 있습니다.

하지만, 대부분의 웹 브라우저들은 Content-Type 헤더에서 문자 인코딩을 명시하지 않은 경우에도, 기본적으로 UTF-8 인코딩으로 가정합니다. 따라서, 한글과 같은 멀티바이트 문자를 전송해도 깨지지 않는 것입니다.

하지만 이는 브라우저에 따라 다를 수 있으며, Content-Type 헤더에서 문자 인코딩을 명시하는 것이 안전하며 권장되는 방법입니다. 또한, 서버에서 보내는 데이터가 브라우저 뿐만 아니라 다른 클라이언트에서도 사용될 경우, 문자 인코딩을 명시하는 것이 더욱 중요합니다.

마무리

헤더에서 응답해줄 데이터 타입의 종류나 문자 인코딩 방식을 지정해주지 않아도 브라우저는 응답받은 본문을 추론하여 위 메타데이터들을 인식합니다.

하지만 이는 모든 브라우저에서 적용되지 않을 수 있고 예기치 못한 상황들이 발생할 수 있기 때문에 헤더를 명시적으로 설정해주는 것이 좋습니다.

브라우저가 알아서해주지만 그래도 친절히 헤더를 작성해줘야하겠습니다.

profile
FE DEVELOPER

0개의 댓글