[React] 리액트 html entity 코드 변환하기(decode)

Bomin·2023년 11월 13일
2

[Side Project]

목록 보기
4/4
post-thumbnail

🔥 문제 상황

왓송에서는 음악 데이터를 서버에서 Youtube API를 이용해 가져오게 된다.

개발하던 중 브라우저에 '와 같은 이상한 문자가 나타나게 되었다.

youtube 데이터에 대한 API 응답에 '' 같은 이상한 문자가 껴있었는데, 이를 처리하지 않고 바로 화면에 보여줘서 나타난 문제였다.

검색을 통해 이 문자들이 HTML entity 코드라는 것을 알게 되었고

방대한 데이터이며 그때 그때 검색할 때마다 변하는 데이터인 만큼 서버에서 이를 변환해서 주는 것이 아니라 프론트에서 변환해서 화면에 보여주는 것이 좋다고 생각했다.

🔎 html entity

HTML 예약어로 마크업언어와 충돌하는 것을 방지하기 위해 HTML에서 규정한 문자열의 코드 규약

자주 사용되는 특수문자

기호Entity NameEntity Number
<<<
>>>
&&&
"""
'''

즉, HTML entity란 특수문자와 같은 특별한 문자와 HTML 문법과의 충돌을 방지하고자 만든 예약어다.

👉 변환 방법은?

HTML entity로 표현된 특수문자를 원래대로 다시 변환하기 위한 방법으로는 라이브러리를 사용하거나 직접 함수를 작성하여 해결할 수 있다.

대표적인 라이브러리 Lodash

// Lodash
import _ from 'lodash';

console.log(_.unescape("&lt;"));); 

직접 함수 작성 예시


const regex = /&(amp|lt|gt|quot|#39);/g;
const chars = {
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>',
    '&quot;': '"',
    '&#39;': "'",
		...(더 많은 entity들...)
}

function unescape(str) {
    if(regex.test(str)) {
        return str.replace(regex, (matched) => chars[matched] || matched);
    }
}

💡 해결 방법

처음엔 직접 함수를 구현하여 해결해보고자 했지만, html entity의 양이 방대하기 때문에 시간 절약을 위해 라이브러리를 사용하기로 했다.

프로젝트에서 사용하지 않는 기능도 제공하는 lodash 라이브러리 대신에 html entity 변환 가능만 제공하는 html-entities 를 사용하기로 했다.

🍏 html-entities

encode(text, options) : text에 문자열를 넣어주면 문자열 속 특수 문자를 html entity 코드로 인코딩해준다.

decode(text, options) : text에 문자열를 넣어주면 문자열 속 html entity 코드를 특수 문자로 디코딩해준다.

🍎 문제 해결

  • 현재 프로젝트에서는 youtube api 응답 데이터의 title에서만 이 문제가 나타났다.
  • youtube api 응답은 리스트 형태로 받아오는데 이에 용이하도록 함수를 만들어 사용했다.
import { decode } from 'html-entities';
import { ResVideo } from '@/types/video';

export const decodeTitle = (list: ResVideo[]) => {
	const decoded = list.map((item) => {
		item.title = decode(item.title);
		return item;
	});
	return decoded;
};
  • 아래와 같이 리스트 형태로 데이터를 받아오는 fetch(axios)함수에 적용하여 문제를 해결하였다.
import client from './client';
import { decodeTitle } from '@/utils/youtube/decode';

export const youtubeApis = {
	serchKeyword: async (body: { keyword: string }) => {
		const res = await client.post('/api/v1/youtube/search', { ...body });
		return decodeTitle(res.data);
	},
};

🐣 마무리

HTML entity에 들어봤어지만 이번 트러블 슈팅을 통해 자세히 알게 되었다. 또한 다양한 변환 방법에 대해서 알게 되었기 때문에 또 이런 상황과 마주하게 된다면 빠르게 문제를 해결할 수 있을 것 같다.

참고자료
https://velog.io/@sisofiy626/JS-HTML-entity와-변환
https://www.npmjs.com/package/html-entities

profile
Frontend-developer

1개의 댓글

comment-user-thumbnail
2023년 11월 13일

글 잘 봤습니다.

답글 달기

관련 채용 정보