url debugging web-development javascript encoding

'URIError: URI malformed' 및 일반적인 URL 오류 해결 방법

'URIError: URI malformed', 'invalid URL', 퍼센트 인코딩 문제와 같은 URL 오류를 수정하는 포괄적인 가이드입니다. encodeURI와 encodeURIComponent의 차이점을 알아보세요.

"URIError: URI malformed" 및 일반적인 URL 오류 해결 방법: 전체 가이드

URL(Uniform Resource Locator)은 웹의 주소입니다. 단순해 보이지만, 어떤 문자가 허용되는지에 대한 엄격한 규칙이 있습니다. 이러한 규칙을 어기면 URIError: URI malformed, TypeError: Failed to construct 'URL': Invalid URL과 같은 오류가 발생하거나 404 페이지로 연결되는 깨진 링크가 생성됩니다.

이 가이드에서는 가장 흔한 URL 관련 오류와 JavaScript 및 기타 환경에서의 해결 방법을 자세히 살펴보겠습니다.


1. 일반적인 URL 오류 메시지

작업 내용에 따라 다음과 같은 오류를 만날 수 있습니다.

  • JavaScript (decodeURIComponent): URIError: URI malformed
  • JavaScript (new URL()): TypeError: Failed to construct 'URL': Invalid URL
  • Python (urllib): ValueError: Invalid URL
  • Java (URLDecoder): java.lang.IllegalArgumentException: URLDecoder: Incomplete % sequence

2. 주요 원인 및 해결 방법

2.1 "URIError: URI malformed"

이 오류는 JavaScript의 decodeURI() 또는 decodeURIComponent()가 유효하지 않은 퍼센트 인코딩(percent encoding error) 시퀀스를 만났을 때 발생합니다. 보통 % 기호 뒤에 두 자리 16진수가 오지 않거나, 시퀀스가 유효하지 않은 UTF-8 문자를 나타낼 때 발생합니다.

오류 예시:

decodeURIComponent("%") // URIError: URI malformed
decodeURIComponent("%E0%A4%A") // URIError: URI malformed (Incomplete)

해결 방법:

  1. 단일 % 기호 이스케이프: 문자열에 인코딩 시퀀스의 일부가 아닌 리터럴 % 기호가 포함된 경우 %25로 이스케이프해야 합니다.
  2. 잘림 확인: 데이터베이스 필드 제한이나 긴 쿼리 매개변수 등으로 인해 URL이 시퀀스 중간에 잘리지 않았는지 확인하세요.
  3. Try-Catch 사용: 디코딩 작업은 항상 try-catch 블록으로 감싸는 것이 좋습니다.
function safeDecode(str) {
  try {
    return decodeURIComponent(str);
  } catch (e) {
    console.error("Malformed URL (잘못된 형식의 URL):", str);
    return str; // 디코딩 실패 시 원본 문자열 반환
  }
}

2.2 encodeURI vs. encodeURIComponent

흔히 하는 실수는 잘못된 인코딩 함수를 사용하여 서버가 요청을 받을 때 invalid URL 오류가 발생하는 것입니다.

  • encodeURI(): 전체 URL에 사용됩니다. URL 구조에서 특별한 의미를 갖는 문자(:, /, ?, #, &, = 등)는 인코딩하지 않습니다.
  • encodeURIComponent(): 개별 매개변수(검색 쿼리나 파일명 등)에 사용됩니다. 몇 가지 기본 문자를 제외한 모든 문자를 인코딩합니다.

잘못된 방법:

const url = "https://example.com/search?q=" + encodeURI("blue/green");
// 결과: https://example.com/search?q=blue/green (/ 문자가 매개변수 구조를 깨뜨림)

올바른 방법:

const url = "https://example.com/search?q=" + encodeURIComponent("blue/green");
// 결과: https://example.com/search?q=blue%2Fgreen (정확함!)

2.3 "TypeError: Invalid URL"

이 오류는 URL 생성자에 유효한 절대 URL이 아닌 문자열(예: https://와 같은 프로토콜 누락)을 전달할 때 발생합니다.

오류 예시:

new URL("www.google.com") // TypeError: Invalid URL

해결 방법: URL이 절대 주소인지 확인하거나 두 번째 인수로 기본 URL을 제공하세요.

new URL("https://www.google.com") // 올바름
new URL("/path", "https://example.com") // 올바름

2.4 퍼센트 인코딩 오류 (공백 및 특수 문자)

URL에는 공백을 포함할 수 없습니다. 일부 브라우저는 자동으로 공백을 %20 또는 +로 변환하지만, 이 동작에 의존하는 것은 위험합니다.

해결 방법: 동적 데이터는 항상 인코딩하세요.

  • 공백 -> %20 (표준)
  • 공백 -> + (쿼리 문자열에서만 유효, 예: ?q=hello+world)

3. 고급 문제 해결

3.1 이중 인코딩 (Double Encoding)

문자열을 두 번 인코딩하면 엉망이 됩니다. 예를 들어 공백이 %20이 되고, 다시 %2520이 됩니다. 해결 방법: 인코딩이 어디서 일어나는지 추적하세요. 데이터를 URL에 추가하기 직전에 딱 한 번만 인코딩해야 합니다.

3.2 UTF-8 이외의 인코딩

현대 웹은 UTF-8을 사용합니다. GBKLatin1을 사용하는 오래된 시스템의 URL 매개변수를 만나면 decodeURIComponent는 실패하거나 글자 깨짐(mojibake) 현상이 발생합니다. 해결 방법: URL을 처리하기 전에 iconv-lite와 같은 라이브러리를 사용하여 레거시 인코딩을 처리해야 할 수도 있습니다.


4. 예방 및 권장 사항

  1. URL API 사용: 수동으로 문자열을 연결하는 대신 내장된 URLURLSearchParams API를 사용하세요. 인코딩을 자동으로 올바르게 처리해 줍니다.
  2. 용도 구분: 매개변수 값에는 encodeURIComponent를, 기본 경로에는 encodeURI를 사용하세요.
  3. 입력값 검증: 사용자가 제공한 URL의 경우, URL 생성자를 try-catch 블록에서 사용하여 유효성을 검사하세요.
function isValidUrl(string) {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;  
  }
}

5. 자주 묻는 질문 (FAQ)

Q: 공백에 대한 %20과 +의 차이점은 무엇인가요?

A: %20은 URI의 모든 부분에서 공백 문자에 대한 표준 인코딩입니다. +는 주로 쿼리 매개변수(application/x-www-form-urlencoded)에서 사용되는 오래된 관례입니다. 최대 호환성을 위해 %20을 사용하세요.

Q: URL에서 %25가 보이는 이유는 무엇인가요?

A: %25% 문자 자체의 인코딩 버전입니다. 보통 이미 인코딩된 URL이 다시 인코딩될 때(이중 인코딩) 발생합니다.

Q: 이모지나 비라틴 문자가 포함된 URL은 어떻게 처리하나요?

A: 항상 encodeURIComponent를 사용하세요. 유니코드 문자를 UTF-8 바이트 시퀀스로 올바르게 변환한 다음 각 바이트를 퍼센트 인코딩합니다.


6. 빠른 확인 도구

잘못된 형식의 malformed URL 때문에 고민이신가요? 저희의 **URL 인코드 & 디코드 도구**를 사용해 보세요. 다음 기능들을 제공합니다:

  • URL 형식이 올바른지 즉시 검증.
  • encodeURIencodeURIComponent 결과 비교.
  • 복잡한 쿼리 문자열을 안전하게 디코딩.
  • 국제화 도메인 네임(IDN) 처리.

관련 오류

  • JSON의 'Unexpected token' 오류 해결 방법
  • 'invalid base64 string' 오류 수정 방법
  • URIError: URI malformed 이해하기