📙 개요
[url] localhost:3000/profile/플루
현재 URL에 있는 유저 이름을 화면에 렌더링하는 과정에서, 기대했던 '플루' 대신 '%ED%94%8C%EB%A3%A8''라는 문자열이 나타났다.
이 현상이 발생한 원인을 파악하기 위해 작성된 코드를 살펴보자.
📙 문제 분석
import ProfileInfo from "./_component/ProfileInfo";
interface Props {
params: { username: string };
}
export default function ProfilePage({ params }: Props) {
return (
<main>
<section>
<ProfileInfo username={params.username} />
</section>
</main>
);
}
interface Props {
username: string;
}
export default function ProfileInfo({ username }: Props) {
return (
<div>
<div>
<Image
width={240}
height={240}
src='이미지 주소'
alt="사용자 프로필 이미지"
/>
</div>
<div>
<p>{username}</p>
</div>
</div>
);
}
현재 코드는 프로필 페이지에서 params를 컴포넌트의 props로 전달하여 화면에 렌더링하는 구조로 되어 있다.
화면에 표시되는 '%ED%94%8C%EB%A3%A8'는 퍼센트 인코딩 또는 URL 인코딩의 결과값이다.
이는 '플루'라는 한글이 UTF-8로 인코딩되어 ED 94 8C EB A3 A8
라는 바이트 시퀀스가 되고, 퍼센트 인코딩 과정에서 각 바이트 앞에 %
가 추가되어 %ED%94%8C%EB%A3%A8가 된 것이다.
웹에서 URL을 구성하는 경로(path)와 쿼리 스트링(query string)은 ASCII 문자 집합에 속하지 않는 문자(한글, 특수 문자 등)를 직접 사용할 수 없다. 이러한 이유로 퍼센트 인코딩을 사용하여 브라우저와 서버가 URL의 데이터를 올바르게 해석할 수 있게 한다.
📙 decodeURI() / decodeURIComponent()
따라서 URL에 포함된 한글 문자열을 화면에 렌더링하기 위해서는 인코딩/디코딩 처리를 해주어야 한다.
현재 화면에 나타난 문자열은 인코딩된 문자열이므로 디코딩을 진행하면 된다.
JavaScript에서 URL을 디코딩 하는 함수는 decodeURI()
와 decodeURIComponent()
가 있다.
<p>{decodeURI(username)}</p>
혹은
<p>{decodeURIComponent(username)}</p>
그렇다면 decodeURI()
와 decodeURIComponent()
의 차이는 무엇일까?
└ decodeURI()
decodeURI()는 전체 URI를 디코딩할 때 사용한다.
URL 구조에 포함되는 #, ?, &, =
등을 디코딩하지 않는다. 즉 URL의 전체 문자열에서 퍼센트 인코딩된 부분만 디코딩한다.
const uri = "https://example.com/search?query=%ED%95%9C%EA%B8%80&lang=ko";
console.log(decodeURI(uri));
// "https://example.com/search?query=한글&lang=ko"
└ decodeURIComponent()
decodeURIComponent()는 URI의 구성 요소(ex. 쿼리 스트링 값 등)를 디코딩할 때 사용한다.
decodURI()와는 다르게 #, ?, &, =
등을 디코딩 대상에 포함시킨다.
const component = "%ED%95%9C%EA%B8%80%26lang%3Dko";
console.log(decodeURI(component));
console.log(decodeURIComponent(component));
// "한글%26lang%3Dko"
// "한글&lang=ko"
decodeURI()를 쿼리 스트링 값에 사용하면 쿼리 스트링에 포함된 특수 문자는 디코딩되지 않기 때문에 디코딩이 제대로 이뤄지지 않는다.
따라서 쿼리 문자열이나 URI 구성 요소를 처리할 때는 decodeURIComponent()를 사용하는 것이 좋다.
'Face-to-Error' 카테고리의 다른 글
[Next-Auth] 새로고침 시 session을 사용한 부분에 깜빡임 현상 해결하기 (0) | 2025.01.21 |
---|---|
[JavaScript] .js vs .mjs (0) | 2022.12.15 |
[React] Netlify 배포 시 API Key 설정하기 (0) | 2022.10.14 |
[React] Cannot create a project named "xxx" because of npm naming restrictions: (0) | 2022.08.23 |
[React] style 적용 시 발생한 에러: The `style` prop expects a mapping from style properties to values, not a string. (0) | 2022.07.22 |