"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)
해결 방법:
- 단일 % 기호 이스케이프: 문자열에 인코딩 시퀀스의 일부가 아닌 리터럴
%기호가 포함된 경우%25로 이스케이프해야 합니다. - 잘림 확인: 데이터베이스 필드 제한이나 긴 쿼리 매개변수 등으로 인해 URL이 시퀀스 중간에 잘리지 않았는지 확인하세요.
- 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을 사용합니다. GBK나 Latin1을 사용하는 오래된 시스템의 URL 매개변수를 만나면 decodeURIComponent는 실패하거나 글자 깨짐(mojibake) 현상이 발생합니다.
해결 방법: URL을 처리하기 전에 iconv-lite와 같은 라이브러리를 사용하여 레거시 인코딩을 처리해야 할 수도 있습니다.
4. 예방 및 권장 사항
URLAPI 사용: 수동으로 문자열을 연결하는 대신 내장된URL및URLSearchParamsAPI를 사용하세요. 인코딩을 자동으로 올바르게 처리해 줍니다.- 용도 구분: 매개변수 값에는
encodeURIComponent를, 기본 경로에는encodeURI를 사용하세요. - 입력값 검증: 사용자가 제공한 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 형식이 올바른지 즉시 검증.
encodeURI와encodeURIComponent결과 비교.- 복잡한 쿼리 문자열을 안전하게 디코딩.
- 국제화 도메인 네임(IDN) 처리.
관련 오류
- JSON의 'Unexpected token' 오류 해결 방법
- 'invalid base64 string' 오류 수정 방법
- URIError: URI malformed 이해하기