2024. 9. 4. 01:46ㆍ프로그래밍/JavaScript
개요
Javascript의 빌트인 전역 함수인 encodeURI와 encodeURIComponent의 차이점에 대해 이해하고 올바른 사용법에 대해 알아본다.
URL을 인코딩 해야하는 이유?
URI는 우리가 서버 간 통신에서 서로를 식별할 수 있는 유일한 식별자이다. 따라서 영어가 세계 공통 언어이듯이 URI도 이에 맞게 통일 시켜줘야 한다. URI가 변환될 경우 원치 않은 동작이 일어날 수 있기 때문이다.
예를 들어 URL에 한글이 포함돼있는 경우를 생각해보자. 영어를 제외한 다른 나라의 언어는 UTF-8의 형태로 인코딩 돼야만 다른 환경에서도 올바르게 한글로 된 URI를 인식할 수 있을 것이다. 따라서 URL은 아스키 문자로 인코딩 해야 안전한 URI라고 할 수 있다.
encodeURI
encodeURI는 URI 자체는 완전할 경우에 전체 URI에 대해 인코딩을 진행한다. 이 때 인코딩하는 것을 이스케이프 처리 라고 하는데 이스케이프 처리에서 제외되는 문자들이 있다. 문서를 참고해보면 상세히 나와있다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
encodeURI 같은 경우 쿼리 스트링에 사용될 수 있는 ?, &, = 과 같은 특수문자는 인코딩하지 않는다. 즉 쿼리스트링이 없거나 쿼리스트링이 완벽한 상황에서 전체 URI를 필요한 부분만 인코딩 하는 것이다.
encodeURIComponent
이 함수는 encodeURI와는 다르게 동작한다. 즉 인수로 주어지는 URI가 URI전체가 아닌 쿼리 스트링의 일부로 인식하고 인코딩한다. 따라서 encodeURI에서는 이스케이프 처리에서 제외됐던 ?, &, = 과 같은 특수문자도 모두 인코딩 한다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
설명만 들었을 때는 크게 두 함수의 차이점이 와닿지 않는다. 그럼 다음과 같은 상황을 가정해보자.
증명
사용자에게 입력값을 전달받고 이를 쿼리 스트링을 이용해 서버로 요청을 보낸다면 다음과 같은 형식일 것이다.
window.location.href = 'http://example.com?title=안녕하세요? 저는 OO입니다.&body=저는&10살입니다.=1살입니다.';
위와 같이 페이지 이동을 할 경우 어떻게 될까?
사용자의 입력값은 예측할 수 없기 때문에 위와 같은 상황은 충분히 발생할 수 있다.
위 URI의 쿼리스트링은 다음과 같이 분석된다.
title=안녕하세요? 저는 OO입니다.
body=저는
10살입니다.=1살입니다.
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<a onclick = callApi()>Button</a>
</body>
<script>
const callApi = ()=>{
window.location.href = 'http://localhost:3000/test?title=hi?my name is OO.&body=i am&10 years old.=1 years old..'
}
</script>
</html>
위와 같은 결과를 얻을 수 있다. 아마 이 부분은 프레임워크마다 상이할 수 있는데 express로 테스트 한 결과 encodeURI로 URI를 변환한 후에 페이지 이동을 시키는 것을 확인할 수 있었다.
전송된 URI : /test?title=hi?my%20name%20is%20OO.&body=i%20am&10%20years%20old.=1%20years%20old..
그렇다면 위 코드의 URI를 다음과 같이 변경해보자.
window.location.href = `http://localhost:3000/test?title=hi?my name is OO.&body=${encodeURIComponent('i am&10 years old.=1 years old..')}`
위와 같이 쿼리 스트링의 'body' query를 정상적으로 넘겨받는 것을 확인할 수 있다.
전송된 URI : /test?title=hi?my%20name%20is%20OO.&body=i%20am%2610%20years%20old.%3D1%20years%20old..
위에서 설명했듯 encodeURIComponent는 =까지 이스케이프 처리하기 때문에 안전하게 동작할 수 있었던 것이다.
결론
1. encodeURIComponent는 사용자로부터 입력을 받거나 동적으로 변할 수 있는 쿼리 스트링의 value에 사용하도록 한다. 쿼리 스트링이 아닌 URI에 포함되는 공백이나 특수문자의 경우 어차피 encodeURI를 통해 안전하게 이스케이프 처리 되기 때문이다.
2. 사용자로부터 특수문자와 같은 예외 케이스로 URI가 결정되지 않는다면, 즉 서버에서 URI를 생성하거나 ?, &, =과 같은 특수문자가 포함되지 않은 URI를 생성하는 것이 보장될 때(완전한 URI)는 encodeURI를 통해 변환하는 것이 안전하다고 생각한다.
'프로그래밍 > JavaScript' 카테고리의 다른 글
[Javascript] 배열을 비동기 처리하기 위한 Promise.all()의 사용법 (0) | 2025.01.23 |
---|---|
[ Javascript ] 함수 호이스팅, 함수 선언문과 표현식, 함수 리터럴 (0) | 2024.07.28 |
[ Javascript ] 변수 및 객체가 복사 및 할당되는 원리 & 얕은 복사와 깊은 복사 (2) | 2024.07.25 |
[ Javascript ] 암묵적 캐스팅과 산술 연산자 +의 문자열 형변환 (0) | 2024.07.19 |
[ Javascript ] Javascript의 변수 선언과 초기화 동작 원리 및 숫자(number) 타입의 크기 (0) | 2024.07.18 |