Einfache URL-Bearbeitung mit URLSearchParams

Die URLSearchParams API bietet eine einheitliche Schnittstelle zu den einzelnen Teilen der URL und ermöglicht eine einfache Manipulation des Abfragestrings (das, was nach ? kommt).

Traditionell verwenden Entwickler reguläre Ausdrücke und String-Spaltung, um Abfrageparameter aus der URL zu extrahieren. Wenn wir ehrlich sind, macht das keinen Spaß. Das kann mühsam und fehleranfällig sein. Eines meiner dunkelsten Geheimnisse ist, dass ich dieselben get|set|removeURLParameter Hilfsmethoden in mehreren großen Google.com-Apps wiederverwendet habe, darunter der Google Santa Tracker und die Google I/O 2015-Webversion.

Es ist an der Zeit für eine richtige API, die diese Aufgaben für uns erledigt.

URLSearchParams API

Demo ausprobieren

Chrome 49 implementiert URLSearchParams aus der URL-Spezifikation, einer API, die sich zum Ausprobieren von URL-Suchparametern eignet. Ich sehe URLSearchParams als eine für URLs ebenso praktische Lösung wie FormData für Formulare.

Was können Sie damit tun? Anhand eines URL-Strings können Sie ganz einfach Parameterwerte extrahieren:

// 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);
}

Legen Sie einen Parameterwert fest:

params.set('version', 2);

Sie können einen weiteren Wert an einen vorhandenen Parameter anhängen:

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

Parameter löschen:

params.delete('person');

Mit URLs arbeiten

In den meisten Fällen arbeiten Sie wahrscheinlich mit vollständigen URLs oder ändern die URL Ihrer App. Der URL-Konstruktor kann in folgenden Fällen besonders nützlich sein:

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'

Wenn Sie tatsächlich Änderungen an der URL vornehmen möchten, können Sie Parameter abrufen, ihre Werte aktualisieren und dann die URL mit history.replaceState aktualisieren.

// 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

Hier habe ich ES6-Template-Strings verwendet, um eine aktualisierte URL aus dem vorhandenen URL-Pfad der App und den geänderten Parametern zu rekonstruieren.

Integration mit anderen Orts-URLs

Wenn du FormData in einer fetch() API-Anfrage sendest, wird standardmäßig ein mehrteiliger Textkörper erstellt. Bei Bedarf bietet URLSearchParams einen alternativen Mechanismus für POST-Daten, der nicht MIME-multipart, sondern URL-codiert ist.

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

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

URLSearchParams ist zwar noch nicht in Chrome implementiert, lässt sich aber auch in den Konstruktor URL und die a-Tags einbinden. Beide unterstützen unseren neuen Freund, indem sie eine schreibgeschützte Property namens .searchParams für den Zugriff auf Abfrageparameter bereitstellen:

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

Links erhalten auch eine .searchParams-Property:

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

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

Funktionserkennung und Browserunterstützung

Derzeit wird URLSearchParams von Chrome 49, Firefox 44 und Opera 36 unterstützt.

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

Ich empfehle die Polyfills unter github.com/WebReflection/url-search-params.

Demo

Probieren Sie es aus.

URLSearchParams in einer echten App sehen, können Sie den Material Design Iconset Generator von Polymer verwenden. Ich habe damit den Anfangsstatus der App über einen Deeplink eingerichtet. Sehr praktisch :)