Manipulación sencilla de URL con URLSearchParams

La API de URLSearchParams proporciona una interfaz coherente para los bits y las partes de la URL y permite la manipulación trivial de la cadena de consulta (esos elementos después de ?).

Tradicionalmente, los desarrolladores usan regex y división de cadenas para extraer parámetros de consulta de la URL. Si somos honestos con nosotros mismos, eso no es divertido. Puede ser tedioso y propenso a errores. Uno de mis secretos oscuros es que reutilicé los mismos métodos de ayuda de get|set|removeURLParameter en varias apps grandes de Google.com, como Sigue a Papá Noel de Google y el sitio web de Google I/O 2015.

Es hora de una API adecuada que haga esto por nosotros.

API de URLSearchParams

Prueba la demostración

En Chrome 49, se implementa URLSearchParams de especificaciones de URL, una API que es útil para explorar los parámetros de consulta de URL. Pienso en URLSearchParams como una conveniencia equivalente a las URLs, así como FormData lo era para los formularios.

¿Qué puedes hacer con ella? Si tienes una cadena de URL, puedes extraer fácilmente los valores de los parámetros:

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

Establece un valor de parámetro:

params.set('version', 2);

Agrega otro valor para un parámetro existente:

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

borrar uno o más parámetros:

params.delete('person');

Cómo trabajar con URLs

La mayor parte del tiempo, es probable que trabajes con URLs completas o que modifiques la URL de tu app. El constructor URL puede ser particularmente útil en estos casos:

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'

Para realizar cambios reales en la URL, puedes obtener parámetros, actualizar sus valores y, luego, usar history.replaceState para actualizar la 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

Aquí, usé cadenas de plantilla de ES6 para reconstruir una URL actualizada a partir de la ruta de URL existente de la app y los parámetros modificados.

Se usan URLs de integración con otros lugares

De forma predeterminada, enviar FormData en una solicitud a la API de fetch() crea un cuerpo de varias partes. Si lo necesitas, URLSearchParams proporciona un mecanismo alternativo para enviar datos POST que están codificados en URL en lugar de mime multipart.

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

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

Aunque aún no se implementa en Chrome, URLSearchParams también se integra con el constructor URL y las etiquetas a. Ambos admiten nuestro nuevo amigo, ya que proporcionan una propiedad de solo lectura, .searchParams, para acceder a los parámetros de consulta:

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

Los vínculos también reciben una propiedad .searchParams:

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

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

Detección de funciones y compatibilidad con navegadores

Actualmente, Chrome 49, Firefox 44 y Opera 36 admiten URLSearchParams.

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

Para los polyfills, te recomiendo el que se encuentra en github.com/WebReflection/url-search-params.

Demostración

Prueba el ejemplo.

Para ver URLSearchParams en una app real, consulta el generador de conjuntos de íconos de material design de Polymer. Lo usé para configurar el estado inicial de la app desde un vínculo directo. Muy útil :)