URLSearchParams를 사용한 간편한 URL 조작

에릭 비델만

URLSearchParams API는 URL의 부분과 부분에 일관된 인터페이스를 제공하고 쿼리 문자열 (? 이후의 항목)을 간단하게 조작할 수 있습니다.

일반적으로 개발자는 정규식과 문자열 분할을 사용하여 URL에서 쿼리 매개변수를 가져옵니다. 우리 모두가 솔직하다면, 그것은 재미있지 않습니다. 이는 번거롭고 오류가 발생하기 쉽습니다. 저의 어두운 비밀 중 하나는 Google 산타 추적기Google I/O 2015 웹을 비롯한 여러 대형 Google.com 앱에서 동일한 get|set|removeURLParameter 도우미 메서드를 재사용했다는 것입니다.

이제 이 작업을 처리해 주는 적절한 API가 필요합니다.

URLSearchParams API

데모 사용해 보기

Chrome 49는 URL 쿼리 매개변수를 조작하는 데 유용한 API인 URL 사양URLSearchParams를 구현합니다. URLSearchParams는 양식에 대한 FormData처럼 URL의 편의성에 해당한다고 생각합니다.

그렇다면 이 데이터로 무엇을 할 수 있을까요? URL 문자열이 주어지면 매개변수 값을 쉽게 추출할 수 있습니다.

// Can also constructor from another URLSearchParams
const params = new URLSearchParams('q=search+string&version=1&person=Eric');

params.get('q') === "search string"
params.get('version') === "1"
Array.from(params).length === 3
for (let p of params) {
    console.log(p);
}

매개변수 값을 설정합니다.

params.set('version', 2);

기존 매개변수에 다른 값을 append합니다.

params.append('person', 'Tim');
params.getAll('person') === ['Eric', 'Tim']

매개변수를 삭제합니다.

params.delete('person');

URL 사용

대부분의 경우 전체 URL을 사용하거나 앱의 URL을 수정합니다. URL 생성자는 다음과 같은 경우에 특히 편리할 수 있습니다.

const url = new URL('https://example.com?foo=1&bar=2');
const params = new URLSearchParams(url.search);
params.set('baz', 3);

params.has('baz') === true
params.toString() === 'foo=1&bar=2&baz=3'

URL을 실제로 변경하려면 매개변수를 가져오고 그 값을 업데이트한 다음 history.replaceState를 사용하여 URL을 업데이트하면 됩니다.

// URL: https://example.com?version=1.0
const params = new URLSearchParams(location.search);
params.set('version', 2.0);

window.history.replaceState({}, '', `${location.pathname}?${params}`);
// URL: https://example.com?version=2.0

여기에서는 ES6 템플릿 문자열을 사용하여 앱의 기존 URL 경로와 수정된 매개변수로부터 업데이트된 URL을 재구성했습니다.

URL이 사용되는 다른 위치와의 통합

기본적으로 fetch() API 요청에 FormData를 전송하면 멀티파트 본문이 생성됩니다. 필요한 경우 URLSearchParams는 MIME 멀티파트가 아닌 URL 인코딩된 POST 데이터의 대체 메커니즘을 제공합니다.

const params = new URLSearchParams();
params.append('api_key', '1234567890');

fetch('https://example.com/api', {
    method: 'POST',
    body: params
}).then(...)

URLSearchParams는 아직 Chrome에서 구현되지 않았지만 URL 생성자 및 a 태그와도 통합됩니다. 둘 다 쿼리 매개변수에 액세스하기 위한 읽기 전용 속성인 .searchParams를 제공하여 새 친구를 지원합니다.

const url = new URL(location);
const foo = url.searchParams.get('foo') || 'somedefault';

링크는 .searchParams 속성도 가져옵니다.

const a = document.createElement('a');
a.href = 'https://example.com?filter=api';

// a.searchParams.get('filter') === 'api';

기능 감지 및 브라우저 지원

현재 Chrome 49, Firefox 44, Opera 36은 URLSearchParams를 지원합니다.

if ('URLSearchParams' in window) {
    // Browser supports URLSearchParams
}

폴리필의 경우 github.com/WebReflection/url-search-params에 있는 것을 권장합니다.

데모

샘플을 사용해 보세요.

실제 앱에서 URLSearchParams를 보려면 Polymer의 머티리얼 디자인 Iconset Generator를 확인하세요. 저는 이 도구를 사용하여 딥 링크에서 앱의 초기 상태를 설정했습니다. 정말 편리해요 :)