자바스크립트7분 분량

encodeURI와 encodeURIComponent의 차이점은 무엇인가요?

encodeURI는 /, ?, # 같은 구조적 문자를 그대로 유지하면서 전체 URL을 인코딩합니다. encodeURIComponent는 단일 URI 구성 요소를 인코딩하며 /, ?, & 를 포함한 모든 특수 문자를 인코딩합니다. 쿼리 파라미터 값에는 encodeURIComponent를, 완전한 URL에는 encodeURI를 사용하세요.

encodeURI()란 무엇인가요?

encodeURI()는 완전한 URI(Uniform Resource Identifier)를 인코딩하도록 설계된 자바스크립트 내장 함수입니다. URI에서 유효하지 않은 문자를 percent-encoding된 형태로 변환하되, URI 내에서 구조적 의미를 갖는 문자는 의도적으로 그대로 보존합니다.

구체적으로 encodeURI()는 다음 문자들을 인코딩하지 않습니다: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #. 즉, 인코딩 후에도 URL의 전체 구조가 그대로 유지됩니다.

// encodeURI()는 URL 구조를 보존합니다
const url = 'https://example.com/my page?name=John Doe&city=New York';
console.log(encodeURI(url));
// "https://example.com/my%20page?name=John%20Doe&city=New%20York"
// 주목: :, /, ?, &, = 는 인코딩되지 않습니다

이러한 동작 덕분에 encodeURI()는 공백이나 비 ASCII 문자가 포함될 수 있지만 구조적 문자(프로토콜 구분자, 경로 구분자, 쿼리 문자열 표시자)는 그대로 유지해야 하는 완전한 URL을 다룰 때 이상적입니다.

encodeURIComponent()란 무엇인가요?

encodeURIComponent()는 쿼리 파라미터 값이나 경로 세그먼트처럼 URI의 단일 구성 요소를 인코딩하도록 설계되었습니다. encodeURI()와 달리, URL에서 구조적 의미를 갖는 문자를 포함하여 거의 모든 특수 문자를 인코딩합니다.

encodeURIComponent()가 인코딩하지 않는 문자는 오직 A-Z a-z 0-9 - _ . ! ~ * ' ( ) 뿐입니다. /, ?, &, =, #, : 를 포함한 그 밖의 모든 문자는 percent-encoding됩니다.

// encodeURIComponent()는 비예약 문자를 제외한 모든 것을 인코딩합니다
const value = 'Tom & Jerry / Friends?';
console.log(encodeURIComponent(value));
// "Tom%20%26%20Jerry%20%2F%20Friends%3F"
// 주목: &, /, ? 는 인코딩됩니다

// 쿼리 파라미터를 포함한 URL 만들기
const url = 'https://example.com/search?q=' + encodeURIComponent(value);
// "https://example.com/search?q=Tom%20%26%20Jerry%20%2F%20Friends%3F"

구조적 문자까지 인코딩하기 때문에, 완전한 URL에 encodeURIComponent()를 사용해서는 절대 안 됩니다. 그렇게 하면 ://, 모든 / 경로 구분자, 그리고 ? 쿼리 구분자까지 인코딩되어 URL을 사용할 수 없게 됩니다.

핵심 차이점 한눈에 보기

항목 encodeURI() encodeURIComponent()
용도 전체 URI 인코딩 URI 구성 요소 인코딩
/ 인코딩 아니오 예 (%2F)
? 인코딩 아니오 예 (%3F)
& 인코딩 아니오 예 (%26)
= 인코딩 아니오 예 (%3D)
# 인코딩 아니오 예 (%23)
: 인코딩 아니오 예 (%3A)
공백 인코딩 예 (%20) 예 (%20)
유니코드 인코딩

각 함수를 언제 사용해야 하나요?

규칙은 간단합니다. 완전한 URL을 인코딩하면서 그 구조를 유효하게 유지하고 싶을 때는 encodeURI()를 사용하세요. URL에 삽입될 단일 값을 인코딩하고 싶을 때는 encodeURIComponent()를 사용하세요.

// 시나리오 1: 공백이 포함된 완전한 URL 인코딩
const fullUrl = 'https://example.com/my documents/file name.pdf';
const encoded = encodeURI(fullUrl);
// "https://example.com/my%20documents/file%20name.pdf"

// 시나리오 2: 여러 부분을 조합해 URL 만들기
const baseUrl = 'https://api.example.com/search';
const query = 'price >= 100 & category = books';
const finalUrl = baseUrl + '?q=' + encodeURIComponent(query);
// "https://api.example.com/search?q=price%20%3E%3D%20100%20%26%20category%20%3D%20books"

// 시나리오 3: 리다이렉트 URL을 파라미터로 인코딩
const redirectUrl = 'https://example.com/callback?token=abc';
const loginUrl = 'https://auth.example.com/login?redirect=' +
  encodeURIComponent(redirectUrl);
// 리다이렉트 URL 전체가 하나의 파라미터 값으로 인코딩됩니다

흔한 실수와 이를 피하는 방법

실수 1: 쿼리 파라미터 값에 encodeURI()를 사용하는 경우. encodeURI()&=를 인코딩하지 않기 때문에, 이런 문자가 포함된 파라미터 값에 사용하면 쿼리 문자열 구조가 손상됩니다.

// 잘못된 예
const bad = 'https://example.com/search?q=' + encodeURI('salt & pepper');
// "https://example.com/search?q=salt%20&%20pepper"
// 서버는 q="salt " 와 별개의 파라미터 " pepper" 로 인식합니다

// 올바른 예
const good = 'https://example.com/search?q=' + encodeURIComponent('salt & pepper');
// "https://example.com/search?q=salt%20%26%20pepper"

실수 2: 전체 URL에 encodeURIComponent()를 사용하는 경우. 모든 슬래시, 콜론, 물음표가 인코딩되어 URL 구조가 파괴됩니다.

// 잘못된 예
console.log(encodeURIComponent('https://example.com/path?key=value'));
// "https%3A%2F%2Fexample.com%2Fpath%3Fkey%3Dvalue"
// 더 이상 유효한 URL이 아닙니다!

// 올바른 예
console.log(encodeURI('https://example.com/path?key=value'));
// "https://example.com/path?key=value" (이미 유효하므로 인코딩할 것이 없습니다)

실수 3: 이중 인코딩. 이미 percent-encoding된 문자열을 다시 인코딩하면 % 기호가 인코딩되어 %20%2520으로 바뀝니다. 인코딩 함수를 적용하기 전에 값이 이미 인코딩되어 있는지 항상 확인하세요.

더 안전한 최신 대안은 URLURLSearchParams API로, 이들은 인코딩을 자동으로 처리하여 이러한 함정을 완전히 피할 수 있게 도와줍니다.

관련 글

무료 도구 사용해 보기