encodeURIComponent vs encodeURI: 언제 무엇을 써야 할까
자바스크립트의 encodeURIComponent()와 encodeURI() 함수를 예제와 모범 사례를 통해 자세히 비교합니다.
자바스크립트의 두 가지 URL 인코딩 함수
자바스크립트는 URL 인코딩을 위한 두 가지 내장 함수를 제공합니다. 바로 encodeURI()와 encodeURIComponent()입니다. 두 함수는 비슷해 보이지만, 잘못된 함수를 사용하면 URL이 깨지거나 보안 취약점이 생기거나 데이터가 손상될 수 있습니다. 따라서 이 둘의 차이를 이해하는 것은 웹 개발자에게 매우 중요합니다.
encodeURI() - 완전한 URI를 위한 함수
encodeURI()는 완전한 URI를 인코딩하도록 설계되었습니다. 이 함수는 URI 구조에서 특별한 의미를 가지는 문자를 제외한 모든 문자를 인코딩합니다. 구체적으로, 다음 문자들은 인코딩하지 않습니다.
- 예약 문자(reserved characters):
; , / ? : @ & = + $ # - 비예약 문자(unreserved characters): 영문자, 숫자,
- _ . ! ~ * ' ( )
// encodeURI는 URI 구조를 그대로 유지합니다
encodeURI('https://example.com/path?q=hello world&lang=en')
// "https://example.com/path?q=hello%20world&lang=en"
// 참고: :, /, ?, =, & 는 인코딩되지 않습니다
encodeURIComponent() - URI 구성 요소를 위한 함수
encodeURIComponent()는 URI의 개별 구성 요소(예: 쿼리 파라미터 값)를 인코딩하도록 설계되었습니다. 이 함수는 다음을 제외한 모든 문자를 인코딩합니다.
- 비예약 문자(unreserved characters): 영문자, 숫자,
- _ . ! ~ * ' ( )
// encodeURIComponent는 비예약 문자를 제외한 모든 것을 인코딩합니다
encodeURIComponent('hello world & goodbye')
// "hello%20world%20%26%20goodbye"
// 참고: &는 예약 문자이므로 인코딩됩니다
// 쿼리 파라미터 값으로 사용하기
const url = 'https://example.com/search?q=' +
encodeURIComponent('cats & dogs');
// "https://example.com/search?q=cats%20%26%20dogs"
흔히 저지르는 실수
실수 1: 쿼리 값에 encodeURI 사용하기
앰퍼샌드(&)가 포함된 쿼리 파라미터 값을 encodeURI()로 인코딩하면, 앰퍼샌드가 인코딩되지 않아 파라미터 구분자로 해석되어 URL이 깨집니다.
// 잘못된 예: 값에 포함된 앰퍼샌드가 URL을 깨뜨립니다
const badUrl = 'https://api.example.com/search?q=' +
encodeURI('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20&%20Jerry"
// 서버는 q="Tom " 과 값이 없는 파라미터 " Jerry" 로 인식합니다
// 올바른 예: encodeURIComponent를 사용합니다
const goodUrl = 'https://api.example.com/search?q=' +
encodeURIComponent('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20%26%20Jerry"
// 서버는 q="Tom & Jerry" 로 올바르게 인식합니다
실수 2: 전체 URL에 encodeURIComponent 사용하기
URL 전체에 encodeURIComponent()를 사용하면 콜론, 슬래시, 물음표를 비롯한 구조적 문자까지 모두 인코딩되어 URL을 완전히 사용할 수 없게 됩니다.
언제 무엇을 쓸까: 간단한 규칙
- 구조는 유효하지만 공백이나 non-ASCII 문자가 포함될 수 있는 완전한 URI가 있을 때는
encodeURI()를 사용하세요. - URI에 삽입될 개별 데이터 조각(쿼리 파라미터 값, 경로 세그먼트 등)을 인코딩할 때는
encodeURIComponent()를 사용하세요.
URLSearchParams라는 대안
최신 자바스크립트는 인코딩을 자동으로 처리해 주는 URLSearchParams API를 제공합니다. 쿼리 문자열을 만들 때 이 방법이 가장 좋은 선택인 경우가 많습니다.
const params = new URLSearchParams({
q: 'Tom & Jerry',
category: 'cartoons & animation',
page: '1'
});
const url = 'https://example.com/search?' + params.toString();
// "https://example.com/search?q=Tom+%26+Jerry&category=cartoons+%26+animation&page=1"
// 또는 URL API를 사용합니다
const url2 = new URL('https://example.com/search');
url2.searchParams.set('q', 'Tom & Jerry');
console.log(url2.toString());