Python/python

url에 쿼리스트링으로 데이터 넘길때 예약문자 인코딩문제

알면 알 수록 재밌다! 2023. 10. 25. 12:12

 

문제상황

웹에서 GET 메소드로 어떤 값을 넘겨줄때, +나 &가 생략이 되거나 읽지 못하는 문제가 발생했다.

 


문제이유

쿼리스트링에서 + 기호는 URL을 통해 요청을 보낼 때 공백(space)과 + 기호는 모두 공백(space)으로 치환된다.

이것은 브라우저의 표준 동작이다.

 

따라서 + 기호가 %2B로 인코딩되는데, 이가 공백으로 인식된다는 것이다.

참고로 공백의 인코딩값은 %20이다.

즉, %2B == %20 이다라는 말이된다.(이상한데..?)

 


요약하자면, 서버 프레임워크가 사용자가 입력한 특수문자를 치환해버려서 프론트에서 그 특수문자를 보고 싶을때 다른 값이 나와버린다는 것이다.

 

그 이유는 W3c 표준때문이며... 설명하자면 아래의 2가지 상황일 때, 발생할 수 있다는 것이다.

 

1. form 속성값이 post인 경우

form은 컨트롤 요소(control element)로 구성되는데, form 속성값이 post인 경우에

- text/plain 공백 문자(space)는 "+" 기호로 변환하지만, 나머지 문자는 모두 인코딩되지 않음을 명시함.

 

2. url 쿼리스트링에 넣었을 경우

즉, application/x-www-form-urlencoded로 인코딩된 쿼리 문자열의 경우 공백을 +로 대체한다. 그러나 이는 URL 인코딩 규칙의 한 부분이며, 일반적인 경우에는 + 기호와 공백은 서로 다른 문자로 처리된다고 한다.

 


해결방안

 

1. form 속성값이 post인 경우의 해결방안

 

form으로 post 속성을 사용하는 것 말고  fetch로 post api를 호출한다.

 

왜냐하면, fetch와 같은 JavaScript API를 사용할 때, URL 인코딩 및 디코딩 규칙을 명시적으로 다룰 수 있기 때문이다.

그래서 %20%2B와 같은 값들을 직접 처리할 수 있다.

이로 인해 JavaScript에서 URL을 직접 만들 때 +%2B로 처리되는 것이다.

 

 

2. 퍼센트 인코딩을 사용한다.

 

퍼센트 인코딩(percent-encoding) URL 문자를 표현하는 문자 인코딩 방법이다. 이 방법에 따르면 알파벳이나 숫자 등 몇몇 문자를 제외한 값은 옥텟 단위로 묶어서, 16진수 값으로 인코딩한다.

그러니까 예약 문자는 URL에서 특별한 의미가 있거나 특수한 용도로 사용되는 문자이다.

이러한 문자를 그대로 URL에 사용하면 오류를 유발할 수 있으므로 퍼센트 인코딩을 사용하여 어떤 문자인지를 알 수 있다.

 

encodeURI( uri ) : URI에서 자주 사용하는 : ; / = ? & 등을 제외하고 인코딩하는 함수
decodeURI( uri ) : encoding 된 URI를 디코딩하는 함수
encodeURIComponent( uri ) : 모든 문자를 인코딩하는 함수
decoudeURIComponent ( uri ) : encodeURIComponent의 결과물을 디코딩하는 함수

 

참고로 아래와 같이 인코딩된다.

슬래시 (/) : %2F
물음표 (?) : %3F
등호 (=) : %3D
앰퍼샌드 (&) : %26
공백 (빈 칸) : %20
더하기 (+) : %2B

 


http://www.tcpschool.com/html-tag-attrs/form-enctype

https://ko.wikipedia.org/wiki/%ED%8D%BC%EC%84%BC%ED%8A%B8_%EC%9D%B8%EC%BD%94%EB%94%A9

https://it-eldorado.tistory.com/143

https://steady-snail.tistory.com/111