> 웹 프론트엔드 > JS 튜토리얼 > JavaScript의 URL 및 URLSearchParams의 함정

JavaScript의 URL 및 URLSearchParams의 함정

Mary-Kate Olsen
풀어 주다: 2024-11-28 11:59:09
원래의
494명이 탐색했습니다.

Pitfalls of URL and URLSearchParams in JavaScript

모든 것은 버그로 시작되었습니다

JavaScript 및 Node.js에서 URL 작업은 간단해야 하지만 최근 프로젝트의 버그로 인해 URL 및 URLSearchParams API에 미묘한 문제가 발생했습니다. 이 게시물에서는 이러한 이상한 점, 이것이 코드에서 어떻게 문제를 일으킬 수 있는지, 그리고 이를 방지하기 위해 무엇을 할 수 있는지 살펴보겠습니다.


문제: Axios를 사용한 URL 처리

URL을 생성하고 여기에 해시 서명을 추가하는 동안 이 문제가 발생했습니다. 쿼리 매개변수가 일관되게 퍼센트 인코딩되지 않아 예상치 못한 동작과 잘못된 해시 서명이 발생했습니다.

URL과 URLSearchParams 개체 간의 상호 작용에는 특별한 주의가 필요하다는 것이 분명해졌습니다.


함정 #1: URL.search 대 URLSearchParams.toString()

첫 번째로 놀랐던 점은 URL.search와 URLSearchParams.toString()의 차이점이었습니다.

WHATWG 사양에 따라 URLSearchParams 개체는 다른 규칙을 사용하여 퍼센트 인코딩할 문자를 결정하므로 .searchParams를 사용하여 URL을 수정할 때는 주의하세요. 예를 들어, URL 객체는 ASCII 물결표(~) 문자를 퍼센트 인코딩하지 않지만 URLSearchParams는 항상 이를 인코딩합니다.

// Example 1
const url = new URL("https://example.com?param=foo bar");
console.log(url.search); // prints param=foo%20bar
console.log(url.searchParams.toString()); // prints ?param=foo+bar

// Example 2
const myURL = new URL('https://example.org/abc?foo=~bar');
console.log(myURL.search);  // prints ?foo=~bar
// Modify the URL via searchParams...
myURL.searchParams.sort();
console.log(myURL.search);  // prints ?foo=%7Ebar
로그인 후 복사
로그인 후 복사

우리 프로젝트에서는 쿼리 문자열이 일관되게 인코딩되었는지 확인하기 위해 url.search = url.searchParams.toString()을 명시적으로 다시 할당해야 했습니다.


함정 #2: 더하기 기호 딜레마

또 다른 문제는 URLSearchParams가 문자를 처리하는 방식입니다. 기본적으로 URLSearchParams는 공백으로 해석되므로 바이너리 데이터 또는 Base64 문자열을 인코딩할 때 데이터가 손상될 수 있습니다.

const params = new URLSearchParams("bin=E+AXQB+A");
console.log(params.get("bin")); // "E AXQB A"
로그인 후 복사
로그인 후 복사

한 가지 해결책은 URLSearchParams에 값을 추가하기 전에 encodeURIComponent를 사용하는 것입니다.

params.append("bin", encodeURIComponent("E+AXQB+A"));
로그인 후 복사

자세한 내용은 MDN 문서에서 확인할 수 있습니다.


함정 #3: URLSearchParams.get과 URLSearchParams.toString()

URLSearchParams.get과 URLSearchParams.toString의 출력을 비교할 때 또 다른 미묘함이 나타납니다. 예:

const params = new URLSearchParams("?key=value&key=other");
console.log(params.get("key")); // "value" (first occurrence)
console.log(params.toString()); // "key=value&key=other" (all occurrences serialized)
로그인 후 복사

다중 값 시나리오에서 get은 첫 번째 값만 반환하고 toString은 모든 값을 직렬화합니다.


우리 코드베이스의 수정 사항

저희 프로젝트에서는 검색 속성을 명시적으로 재할당하여 문제를 해결했습니다.

url.search = url.searchParams.toString();
url.searchParams.set(
  "hash",
  cryptography.createSha256HmacBase64UrlSafe(url.href, SECRET_KEY ?? "")
);
로그인 후 복사

이렇게 하면 해시 값을 추가하기 전에 모든 쿼리 매개변수가 올바르게 인코딩되었는지 확인할 수 있습니다.


Node.js 쿼리 문자열 모듈

WHATWG URLSearchParams 인터페이스와 쿼리스트링 모듈은 비슷한 목적을 가지고 있지만 쿼리스트링 모듈의 목적은 구분 기호 문자(& 및 =)를 사용자 정의할 수 있다는 점에서 더 일반적입니다. 반면, URLSearchParams API는 URL 쿼리 문자열용으로만 설계되었습니다.

querystring은 URLSearchParams보다 성능이 뛰어나지만 표준화된 API는 아닙니다. 성능이 중요하지 않거나 브라우저 코드와의 호환성이 필요한 경우 URLSearchParams를 사용하세요.

Querystring 모듈과 달리 URLSearchParams를 사용할 경우 배열 값 형태의 중복 키가 허용되지 않습니다. 배열은 모든 배열 요소를 쉼표로 간단히 결합하는 array.toString()을 사용하여 문자열화됩니다.

// Example 1
const url = new URL("https://example.com?param=foo bar");
console.log(url.search); // prints param=foo%20bar
console.log(url.searchParams.toString()); // prints ?param=foo+bar

// Example 2
const myURL = new URL('https://example.org/abc?foo=~bar');
console.log(myURL.search);  // prints ?foo=~bar
// Modify the URL via searchParams...
myURL.searchParams.sort();
console.log(myURL.search);  // prints ?foo=%7Ebar
로그인 후 복사
로그인 후 복사

querystring 모듈을 사용하면 쿼리 문자열 'foo=bar&abc=xyz&abc=123'이 다음으로 구문 분석됩니다.

const params = new URLSearchParams("bin=E+AXQB+A");
console.log(params.get("bin")); // "E AXQB A"
로그인 후 복사
로그인 후 복사

테이크아웃

  1. 주의하세요 URLSearchParams가 특수 문자(예: ~)와 공백을 처리하는 방식에 유의하세요. 필요한 경우 encodeURIComponent를 사용하세요.

  2. 예기치 않은 동작을 방지하려면 URL.search, URLSearchParams.get 및 URLSearchParams.toString의 차이점을 이해하세요.

  3. Node.js에서 중복된 쿼리 매개변수 키를 배열로 구문 분석하려면 querystring 모듈을 사용하세요.

위 내용은 JavaScript의 URL 및 URLSearchParams의 함정의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿