Einfache URL-Bearbeitung mit URLSearchParams

Eric Bidelman

Die URLSearchParams API bietet eine konsistente Schnittstelle zu den Teilen der URL und ermöglicht eine einfache Bearbeitung des Abfragestrings (nach ?).

Traditionell verwenden Entwickler reguläre Ausdrücke und String-Aufteilung, um Abfrageparameter aus der URL abzurufen. Wenn wir alle ehrlich zu uns selbst sind, macht das keinen Spaß. Es kann mühsam und fehleranfällig sein, alles richtig zu machen. Eines meiner dunklen Geheimnisse ist, dass ich dieselben get|set|removeURLParameter-Hilfsmethoden in mehreren großen Google.com-Apps wie Auf den Spuren des Weihnachtsmanns von Google und der Webversion der Google I/O 2015 wiederverwendet habe.

Es ist Zeit für eine richtige API, die das für uns erledigt.

URLSearchParams-API

Demo ausprobieren

In Chrome 49 wird URLSearchParams aus der URL-Spezifikation implementiert, einer API, die zum Herumspielen mit URL-Suchparametern nützlich ist. Ich denke, URLSearchParams ist ein Äquivalent für URLs, wie FormData für Formulare.

Was können Sie also damit machen? Mithilfe eines URL-Strings können Sie 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);

einen weiteren Wert für einen vorhandenen Parameter append:

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

Parameter löschen:

params.delete('person');

Arbeiten mit URLs

Meist werden Sie mit vollständigen URLs arbeiten oder die URL Ihrer App ändern. Der URL-Konstruktor kann in folgenden Fällen besonders praktisch 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ächliche Änderungen an der URL vornehmen möchten, können Sie Parameter abrufen, ihre Werte aktualisieren und dann mit history.replaceState die URL 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-Vorlagenstrings verwendet, um eine aktualisierte URL aus dem vorhandenen URL-Pfad der Anwendung und den geänderten Parametern zu rekonstruieren.

Integration mit anderen Orts-URLs, die verwendet werden

Wenn FormData in einer fetch()-API-Anfrage gesendet wird, wird standardmäßig ein mehrteiliger Text erstellt. Bei Bedarf bietet URLSearchParams einen alternativen Mechanismus für POST-Daten, die URL-codiert und nicht mehrteilige Mime-Daten sind.

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 URL-Konstruktor und in a-Tags einbinden. Beide unterstützen unseren neuen Buddy, indem sie ein schreibgeschütztes Attribut .searchParams für den Zugriff auf Abfrageparameter bereitstellen:

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

Links erhalten auch die Property .searchParams:

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

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

Funktionserkennung und Browserunterstützung

Derzeit unterstützen Chrome 49, Firefox 44 und Opera 36 URLSearchParams.

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

Für Polyfills empfehlen wir den Eintrag unter github.com/WebReflection/url-search-params.

Demo

Beispiel ansehen

Wenn du URLSearchParams in einer echten App sehen möchtest, sieh dir den Iconset Generator für Material Design von Polymer an. Ich habe damit den Ausgangsstatus der App über einen Deeplink eingerichtet. Ziemlich praktisch :)