Node Express 환경에서 axios를 사용하여 HTTP 통신 할 경우에 특정 텍스트 깨지는 상황
해당 상황은 한글만 깨지게 보이는 것이 아니라 data 키 값으로 들어오는 모든 데이터가 깨진다.
서버와 데이터를 주고 받는 과정에서 압축 알고리즘을 사용하여 데이터를 주고 받는다.
예를 들어 1234이라는 글자가 10만번 반복되는 텍스트를 받는다고 할 때 1234를 10만번이 적힌 텍스트를 보내주는 것보다 1234x10만이 물리적으로 적은 텍스트를 사용하여 많은 양의 글자를 보낼 수 있지 않겠는가?
Node에서 axios 사용하여 압축된 응답
을 받는 경우 (ex, gzip, deflate, br) decompress가 잘 동작하지 않는 현상이 발생
한다. 그래서 Node 환경에선 node-fetch 사용을 권고 한다고 한다.
그러나 이미 axios를 사용하고 있는 프로젝트라면 여러 방식으로 통신하는 것이 여러모로 번거롭게 된다. 그렇다면 axios를 사용하여 어떻게 해결하는 것이 좋을까?
차선책으로 Headers에 Accept-Encoding을 적용
하여 요청 HTTP 헤더는 압축 알고리즘이 무엇인지를 알려주어
클라이언트가 이해 가능한 컨텐츠 인코딩이 무엇인지
를 서버에게 알려주면 된다.
서버는 제안된 내용 중 하나를 선택하고 사용하며 Content-Encoding 응답 헤더를 이용해 선택된 것을 클라이언트에게 알려준다.
const headers = {
"Accept-Encoding": "deflate, br",
};
클라이언트와 서버 모두 동일한 압축 알고리즘을 지원해도 서버는 응답의 본문을 압축하지 않고 내보내는 경우도 있다.
두 가지 일반적인 경우가 이런 경우를 발생한다.
const kakaoTokenInfo = await axios({
method: "POST",
url: "https://kauth.kakao.com/oauth/token",
headers: {
"Accept-Encoding": "deflate, br",
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
},
(...)
});
본 코드는 kakao 토큰을 활용한 Oauth 구현하기 위해 사용한 코드를 일부 가져왔다.
클라이언트는 응답시 압축 알고리즘이 무엇인지 몰라서 깨지는 것이어서
카카오 OAuth를 구현에 필요한 Accept-Encoding을 위와 같은 타입으로 적용하니 정상 작동한다.
위에 명시한 포맷 말고도 추가적으로 압축 포맷이 있어서 정리 해보려고 한다.
gzip
32비트 CRC와 함께 Lempel-Ziv coding (LZ77)를 사용하는 압축 포맷.compress
Lempel-Ziv-Welch (LZW) 알고리즘을 사용하는 압축 포맷.deflate
deflate 압축 알고리즘과 함께 zlib 구조를 사용하는 압축 포맷.br
Brotli 알고리즘을 사용하는 압축 포맷.identity
식별 함수(압축하지 않거나 수정하지 않은 경우)를 가리킵니다. 이 값은 존재하지 않은 경우에도 항상 수용 가능하다고 여겨집니다.*
헤더 내에 아직 나열되지 않은 컨텐츠 인코딩이라도 일치됩니다. 헤더가 존재하지 않을 경우, 기본값이 됩니다.;q=
(q값 가중치)weight라고 부르는 상대적인 퀄리티 값을 사용하여 표현한 선호도에 따라 배치된 값입니다.참고 URL : MDN Accept-Encoding