개발

Axios 에서 특수문자 대괄호(bracket) 인코딩 문제

jwonelife 2024. 7. 27. 15:19

Axios 에서 특수문자 대괄호 (bracket  [  ] )  의 인코딩 문제

💬 새로운 프로젝트를 할 때 종종 겪었던 문제인데, 거의 프로젝트 초기에 한번 해두고 잊어버려서 기록을 남긴다.

 

axios 를 통해 API URL 요청시 대괄호(bracket) 문자가 인코딩에서 제외되어 호출되고 있었다.

특정 API 서버에서 대괄호로 인해  500 에러를 뱉는 문제가 있었고, 프론트에서 문자를 직접 인코딩하여 API 를 호출하는 것으로 해결한 내용을 기록한다.

 

axios Github 를 보면 아래와 같은 코드가 있고 URL 을 serialize 할 때 몇개의 특수문자는 인코딩 된 문자에서 특수문자로 되돌리고 있다.

💡 코드 참고: https://github.com/axios/axios/blob/v1.x/lib/helpers/buildURL.js#L6
function encode(val) {
  return encodeURIComponent(val).
    replace(/%3A/gi, ':').
    replace(/%24/g, '$').
    replace(/%2C/gi, ',').
    replace(/%20/g, '+').
    replace(/%5B/gi, '[').
    replace(/%5D/gi, ']'); // 몇개의 특수문자들은 인코딩된 상태에서 다시 특수문자로 되돌리고 있다.
}

 

인코딩을 차이를 확인하기 위해 "[hello]한글" 을 encodeURICompeont 와, axios 의 encode 으로 인코드를 해보면 결과는 아래와 같이 나온다.

encodeURIComponent %5Bhello%5D%ED%95%9C%EA%B8%80
axios 의 encode [hello]%ED%95%9C%EA%B8%80

 

 

해결 방법: axios paramsSerializer 를 이용하여 interceptor 에서 쿼리 스트링을 치환했다.

💡 참고: https://stackoverflow.com/questions/39116731/how-to-prevent-axios-from-encoding-my-request-parameters

 

axios.interceptors.request.use(config => {
  if (config.method === 'get') {
    config.paramsSerializer = this.toParamsSerialize.bind(this);
  }
  return config;
});

toParamsSerialize(params) {
  return querystring.stringify(params, { arrayFormat: 'brackets' });
}

 

 

왜 Axios 는 몇개의 특수문자는 인코딩을 하지 않을까?

aixos 에서 이렇게 몇개의 특수문자는 인코딩에서 제외하는 이유는 알 것 같았지만, 이유를 설명하는 공식 문서나 코멘트는 찾지 못했다. 

Why does Axios not encode all reserved characters? ( 왜 Axios 는 예약된 문자를 모두 인코딩하지 않나요? )

💡 이슈 참고: https://github.com/axios/axios/issues/3027 

 

위와 같이 비슷한 이슈/문의가 많지만 속 시원~한 답변은 찾지는 못해서 (열심히 찾아보지는 않았다)

위 물음에 대한 답변은 ChatGPT 에서 얻은 내용으로 정리한다.

대괄호([ 및 ])가 인코딩되지 않는(않을 수 있는) 이유

Axios는 HTTP 요청을 수행할 때 JavaScript의 URLSearchParams 객체를 사용하여 URL의 쿼리 매개변수를 직렬화합니다. 이때 URLSearchParams는 일반적으로 특수문자들을 인코딩하여 URL의 유효성을 유지합니다. 그러나 경우에 따라 특수문자, 특히 대괄호([ 및 ])가 인코딩되지 않을 수 있습니다.

  1. URLSearchParams 동작 방식:
    • URLSearchParams는 대괄호를 URL의 쿼리 문자열에서 안전한 문자로 간주할 수 있습니다. 이 문자들은 URL의 기본 구조에 영향을 미치지 않기 때문에, 브라우저 및 서버는 이들을 적절하게 처리할 수 있습니다.
    • 대괄호는 JavaScript 객체의 배열이나 객체 표현에 흔히 사용되기 때문에, 일부 구현에서는 이러한 문자를 특별한 의미로 해석하거나 인코딩하지 않을 수 있습니다.
  2. 브라우저 및 서버의 호환성:
    • 대괄호는 URL의 쿼리 문자열에서 종종 배열이나 구조체의 키를 나타내는 데 사용됩니다. 많은 웹 서버 및 브라우저는 이러한 문자가 URL에 포함되는 것을 허용하며, 이를 적절하게 처리합니다.
    • 이 문자가 인코딩되지 않더라도, 서버나 브라우저에서 문제를 일으키지 않도록 설계되어 있을 수 있습니다.
  3. URL 인코딩 규칙:
    • URL 인코딩 규칙에 따르면, 대괄호([ 및 ])는 예약 문자가 아니며, 따라서 반드시 인코딩될 필요는 없습니다. 일부 경우에 대괄호가 URL에 사용되면서도 문제를 일으키지 않는 경우가 많습니다.

 

 

'개발' 카테고리의 다른 글

supabase - select 조건에 and, or 여러개 사용하기  (0) 2024.07.28
Github Actions (깃허브 액션)란?  (0) 2024.07.27