Guía

Parámetros repetidos en una query string: cómo conservarlos

Aprende cómo representar parámetros repetidos, por qué un objeto plano pierde valores y cuándo usar getAll, append o una lista ordenada.

por Tools in a Tab · Publicado el · Revisado el

Respuesta breve

Una query string puede repetir la misma clave y cada aparición es una entrada independiente: tag=astro&tag=seo. Para conservar ambas, usa una lista ordenada de parejas o URLSearchParams.getAll("tag"). Convertirla directamente en un objeto { tag: valor } suele descartar información porque una propiedad solo puede guardar un valor a la vez.

Qué significa realmente repetir una clave

La sintaxis de una URL no obliga a que cada nombre aparezca una sola vez. Esta consulta contiene tres entradas, aunque solo haya dos claves diferentes:

?tag=astro&tag=seo&page=2

El orden observable es tag=astro, tag=seo y page=2. El estándar URL de WHATWG modela URLSearchParams como una lista de pares, no como un diccionario. Por eso get("tag") devuelve el primer valor, mientras que getAll("tag") devuelve ['astro', 'seo']. La API URLSearchParams también distingue append(), que añade otra entrada, de set(), que sustituye el primer valor y elimina los restantes con el mismo nombre.

Formas habituales de representar listas

No existe una única convención universal para arrays en una query. Tres APIs pueden exigir contratos distintos:

tag=astro&tag=seo
tag[]=astro&tag[]=seo
tag=astro,seo

La primera forma repite la clave. La segunda incluye literalmente los corchetes en su nombre. La tercera contiene un solo valor con una coma, que podría ser separador o parte del propio dato. El cliente debe seguir la documentación de la API; cambiar automáticamente entre estas formas puede alterar el significado.

El analizador de query strings muestra una fila por entrada y permite reconstruirlas sin adivinar una convención de arrays. Su JSON usa una lista:

[
  { "key": "tag", "value": "astro" },
  { "key": "tag", "value": "seo" }
]

Espacios, signos más y valores vacíos

URLSearchParams aplica el formato application/x-www-form-urlencoded. Al analizarlo, + se convierte en espacio y %2B se convierte en un signo más literal. Por tanto, q=a+b&q=a%2Bb representa los valores a b y a+b.

También conviene conservar valores vacíos. flag y flag= producen un nombre flag con cadena vacía en URLSearchParams; que una API distinga ambas formas depende de su propio parser. Una clave vacía explícita, como =valor, es otra entrada válida para el modelo aunque probablemente indique un error de contrato.

Patrón seguro en JavaScript

Recorre todas las parejas si necesitas conservar orden y duplicados:

const params = new URLSearchParams(location.search);
const entries = [...params.entries()];
const tags = params.getAll('tag');

Usa append('tag', 'nuevo') para añadir un valor. Usa set() solo cuando quieras deliberadamente una única aparición. Evita Object.fromEntries(params) si los duplicados son significativos: el resultado conservará únicamente el último valor de cada nombre.

Lista de comprobación

  1. Confirma en la documentación cómo representa listas el receptor.
  2. Conserva orden y duplicados durante el análisis.
  3. Distingue un espacio + de un signo más %2B.
  4. Decide de forma explícita si los valores vacíos están permitidos.
  5. Serializa desde parejas, no desde un objeto que ya haya perdido datos.