JavaScript
URL, URLSearchParams y FormData
Explica cómo construir y manipular URLs, parámetros de consulta y formularios con URL, URLSearchParams y FormData en aplicaciones web.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
JavaScript
Explica cómo construir y manipular URLs, parámetros de consulta y formularios con URL, URLSearchParams y FormData en aplicaciones web.
const url = new URL(
"/products",
"https://example.com",
);url.protocol;
url.host;
url.hostname;
url.port;
url.pathname;
url.search;
url.hash;
url.origin;new URL("../images/logo.png", import.meta.url);La resolución sigue reglas de URLs, no concatenación de strings.
const url = baseUrl + "/" + path;Puede producir dobles barras, perder segmentos o manejar mal una URL absoluta.
const url = new URL(path, baseUrl);Ten en cuenta que un path que comienza por / reemplaza el pathname de la base.
const url = new URL("https://example.com/products");
url.searchParams.set("page", "2");
url.searchParams.set("status", "active");Resultado:
https://example.com/products?page=2&status=activeconst params = new URLSearchParams();
params.append("category", "books");
params.append("category", "games");
params.get("category");
params.getAll("category");set reemplaza valores existentes; append añade otro.
params.set("page", 2);
params.get("page"); // "2"Convierte y valida al consumir.
const page = Number(params.get("page"));/products
/products?query=params.has("query");
params.get("query");get devuelve null si no existe y "" si está presente sin contenido.
params.set("query", "café y té");
params.toString();URLSearchParams aplica codificación de formulario. No debes aplicar encodeURIComponent nuevamente a cada valor antes de usar set, porque puede producir doble codificación.
new URLSearchParams({
page: "2",
status: "active",
});Un objeto no representa bien claves repetidas. Para ellas usa pares:
new URLSearchParams([
["category", "books"],
["category", "games"],
]);for (const [key, value] of params) {
console.log(key, value);
}Es iterable y conserva el orden de los pares.
params.sort();Ordena por nombre de clave y puede ser útil para URLs estables o caches. No crea una canonicalización criptográfica completa.
url.hash = "#details";El fragmento no se envía normalmente al servidor HTTP. Es interpretado por el cliente o navegador.
const formData = new FormData(form);Recoge controles exitosos del formulario según reglas HTML.
formData.get("name");
formData.getAll("tags");
formData.has("avatar");formData.set("name", "Nicolás");
formData.append("tag", "javascript");
formData.delete("temporary");const file = formData.get("avatar");
if (file instanceof File) {
console.log(file.name, file.size, file.type);
}Los metadatos del navegador no sustituyen validación del servidor.
await fetch("/api/profile", {
method: "POST",
body: formData,
});No establezcas manualmente Content-Type: multipart/form-data; el navegador añade el boundary correcto.
JSON.stringify(formData); // "{}"Para inspeccionar valores simples:
Object.fromEntries(formData);Pero claves repetidas se pierden y Files siguen siendo objetos File. Define el contrato según la necesidad.
await fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
username,
password,
}),
});No uses esta forma para exponer credenciales en URL; aquí los parámetros forman el body.
const current = new URL(location.href);location pertenece a la ventana. En SSR o Node puede no existir.
function parseHttpUrl(value) {
const url = URL.parse(value);
if (!url || !["http:", "https:"].includes(url.protocol)) {
throw new TypeError("A valid HTTP URL is required");
}
return url;
}URL.parse es una API moderna que devuelve null en lugar de lanzar. Comprueba soporte; el constructor sigue siendo la alternativa ampliamente disponible mediante try/catch.
Validar sintaxis no vuelve confiable el destino. Para redirects, fetches del servidor o embeds debes aplicar allowlists y controles contra protocolos o hosts peligrosos.
function updateFilters(filters) {
const url = new URL(location.href);
for (const [key, value] of Object.entries(filters)) {
if (value === null || value === "") {
url.searchParams.delete(key);
} else {
url.searchParams.set(key, String(value));
}
}
history.replaceState({}, "", url);
}La URL se convierte en una representación compartible del estado.
¿Por qué Object.fromEntries(new FormData(form)) puede perder información?
Porque un objeto solo conserva una propiedad por clave, mientras FormData puede contener varios valores con el mismo nombre.
Web Storage compara localStorage y sessionStorage y explica sus límites de seguridad y rendimiento.