Express.js에서 res.end()와 res.send() 차이, 한글 깨짐
res.end()와 res.send()
res.end()와 res.send()는 둘다 서버측에서 데이터를 전송해준 후 서버의 응답을 종료한다.
처음에는 둘의 차이가 뭔지 몰랐으나 한글 설정을 위해 header설정을 건드리면서 차이점을 알게 되었다.
아래와 같은 코드를 강의를 보고 따라서 작성했다.
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.end("익스프레스 연습중");
});
app.listen(8001);
브라우저를 띄워 localhost:8001번으로 접속해본다.
res.end()를 사용하면 아래와 같이 한글이 깨진다.
검색해보니 한글 깨짐을 해결하기 위해서는 다음 코드를 추가하여 응답객체의 헤드에 데이터 유형을 설정해주면 된다고 한다.
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
그럼 아래와 같은 코드가 된다.
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); // 헤더 설정
res.end("익스프레스 연습중");
});
app.listen(8001);
서버가 잘 응답하고 있고, 한글 표기도 잘 된다.
여기서 res.end()가 아닌 res.send()를 사용하면 응답 헤더 설정이 없어도 곧바로 한글이 잘 나온다.
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("res.send()로 익스프레스 연습중");
});
app.listen(8001);
여기다가 괜히 응답 헤더 설정 코드(앞에서 추가했던)를 추가해 보면
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); // 응답헤더 설정
res.send("익스프레스 연습중");
});
app.listen(8001);
오히려 이렇게 오류가 났다.
오류메시지를 살펴보니
클라이언트에 전송된 이후에는 헤더를 설정할 수 없다고 나온다.
이게 무슨 말일까... 하고 찾아보았다.
res.send()는 자동으로 데이터 유형 등의 응답헤더를 설정해준다고 한다.
그러니까 "익스프레스 연습중"이라는 문자열이 한글이므로 자동으로 Content-Type의 text/html, charset의 utf-8 설정을 알아서 해준다고 한다.
res.writeHead()로 응답 헤더를 설정해줬는데, 아래처럼 res.send()가 또 헤더를 설정하려 하므로 헤더 설정이 중복되어서 충돌이 발생하는 것이다.
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); // 응답헤더 설정
res.send("익스프레스 연습중");
그럼 res.send()는 내 마음대로 응답 헤더를 설정할 수 없는가?
아니오. 설정할 수 있다. 사용하는 메서드가 다를 뿐이다. res.setHeader() 를 사용해서 설정하면 된다.
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.setHeader("Content-Type", "text/html; charset=utf-8"); // 헤더 설정
res.send("익스프레스 연습중");
});
app.listen(8001);
정리
res.end()는 'Content-Type' 등의 응답 헤더를 수동으로 설정해야 한다. 그래서 한글설정(utf-8)을 해주어야 한글이 제대로 표시된다.
res.send()는 자동으로 적절한 'Content-Type'헤더를 설정해준다. 이 과정에서 알아서 한글설정(utf-8)이 된다.
헤더 설정은 res.writeHeader()와 res.setHeader() 두가지가 있는데,
res.end()는 둘 중 무엇을 사용해도 상관없지만
res.send()의 경우는 res.writeHeader()와 병기하면 오류를 일으킨다. (res.send() 내부의 자동 헤더 설정 로직 때문인 듯)
그래서 헤더 설정을 하고 싶으면 res.setHeader()로 설정해주어야 한다.
알고보니 서로 다른 소속인 res.end()와 res.send()
+ 좀 더 찾아보니 res.end()는 Express.js의 메서드가 아니라 Node.js의 http 메서드라고 한다.
Express.js의 메서드인 res.send()가 내부적으로는 res.end() 메서드를 호출하여 응답을 종료시킨다.
이런 점이 공부할 때 헷갈리는 부분인 것 같다. res.end()나 res.send()나 같은 소속(?)일 것이라고 생각했는데 알고보니 다른 것.. 왜 이것도 존재하고 저것도 존재하고 미세하게 기능이 다른가 하면 하나는 원시적인 코드이고 하나는 발전된 프레임워크 소속이고 이런 듯.
'인간은 어떻게 배울까' 카테고리의 다른 글
(M1 mac) mysql.server start 실행 후 ERROR! The server quit without updating PID file 오류 (아나콘다 환경과 충돌) (0) | 2024.06.18 |
---|---|
객체와 참조, Chart.js (0) | 2024.06.18 |
[js] fetch의 .json()과 Express의 .json()의 차이 (0) | 2023.10.19 |
[Mac/M1] Homebrew로 git 설치 & git 버전 변경하기 (0) | 2023.09.29 |
[Mac/M1] Homebrew 설치 후 zsh: command not found 에러 (0) | 2023.09.18 |