Saltar al contenido

¿Cómo puedo obtener valores de cadena de consulta en JavaScript?

Solución:

Actualización: septiembre de 2018

Puede usar URLSearchParams, que es simple y tiene un soporte de navegador decente (pero no completo).

const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');

Original

No necesita jQuery para ese propósito. Puede usar solo algo de JavaScript puro:

function getParameterByName(name, url = window.location.href) {
    name = name.replace(/[[]]/g, '\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/+/g, ' '));
}

Uso:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)

NOTA: Si un parámetro está presente varias veces (?foo=lorem&foo=ipsum), obtendrá el primer valor (lorem). No existe un estándar sobre esto y los usos varían, consulte, por ejemplo, esta pregunta: Posición autorizada de las claves de consulta HTTP GET duplicadas.

NOTA: La función distingue entre mayúsculas y minúsculas. Si prefiere un nombre de parámetro que no distingue entre mayúsculas y minúsculas, agregue el modificador ‘i’ a RegExp


Esta es una actualización basada en las nuevas especificaciones de URLSearchParams para lograr el mismo resultado de manera más sucinta. Consulte la respuesta titulada “URLSearchParams” a continuación.

Algunas de las soluciones publicadas aquí son ineficientes. Repetir la búsqueda de expresiones regulares cada vez que el script necesita acceder a un parámetro es completamente innecesario, una sola función para dividir los parámetros en un objeto de estilo de matriz asociativa es suficiente. Si no está trabajando con la API de historial de HTML 5, esto solo es necesario una vez por carga de página. Las otras sugerencias aquí también fallan al decodificar la URL correctamente.

var urlParams;
(window.onpopstate = function () {
    var match,
        pl     = /+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    urlParams = {};
    while (match = search.exec(query))
       urlParams[decode(match[1])] = decode(match[2]);
})();

Cadena de consulta de ejemplo:

?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty

Resultado:

 urlParams = {
    enc: " Hello ",
    i: "main",
    mode: "front",
    sid: "de8d49b78a85a322c4155015fdce22c4",
    empty: ""
}

alert(urlParams["mode"]);
// -> "front"

alert("empty" in urlParams);
// -> true

Esto podría mejorarse fácilmente para manejar también cadenas de consulta de estilo de matriz. Un ejemplo de esto está aquí, pero dado que los parámetros de estilo de matriz no están definidos en RFC 3986, no contaminaré esta respuesta con el código fuente. Para aquellos interesados ​​en una versión “contaminada”, mire la respuesta de Campbeln a continuación.

Además, como se señala en los comentarios, ; es un delimitador legal para key=value pares. Requeriría una expresión regular más complicada de manejar ; o &, que creo que es innecesario porque es raro que ; se usa y yo diría que es aún más improbable que se usen ambos. Si necesita apoyo ; en lugar de &, simplemente cámbielos en la expresión regular.


Si está utilizando un lenguaje de preprocesamiento del lado del servidor, es posible que desee utilizar sus funciones JSON nativas para hacer el trabajo pesado por usted. Por ejemplo, en PHP puede escribir:

<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>

¡Mucho más sencillo!

ACTUALIZADO

Una nueva capacidad sería recuperar parámetros repetidos de la siguiente manera myparam=1&myparam=2. No hay una especificaciónSin embargo, la mayoría de los enfoques actuales siguen la generación de una matriz.

myparam = ["1", "2"]

Entonces, este es el enfoque para administrarlo:

let urlParams = {};
(window.onpopstate = function () {
    let match,
        pl = /+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
            return decodeURIComponent(s.replace(pl, " "));
        },
        query = window.location.search.substring(1);

    while (match = search.exec(query)) {
        if (decode(match[1]) in urlParams) {
            if (!Array.isArray(urlParams[decode(match[1])])) {
                urlParams[decode(match[1])] = [urlParams[decode(match[1])]];
            }
            urlParams[decode(match[1])].push(decode(match[2]));
        } else {
            urlParams[decode(match[1])] = decode(match[2]);
        }
    }
})();

ES2015 (ES6)

getQueryStringParams = query => {
    return query
        ? (/^[?#]/.test(query) ? query.slice(1) : query)
            .split('&')
            .reduce((params, param) => {
                    let [key, value] = param.split('=');
                    params[key] = value ? decodeURIComponent(value.replace(/+/g, ' ')) : '';
                    return params;
                }, {}
            )
        : {}
};

Sin jQuery

var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
        var p=a[i].split('=', 2);
        if (p.length == 1)
            b[p[0]] = "";
        else
            b[p[0]] = decodeURIComponent(p[1].replace(/+/g, " "));
    }
    return b;
})(window.location.search.substr(1).split('&'));

Con una URL como ?topic=123&name=query+string, volverá lo siguiente:

qs["topic"];    // 123
qs["name"];     // query string
qs["nothere"];  // undefined (object)

Método de Google

Rompiendo el código de Google encontré el método que usan: getUrlParameters

function (b) {
    var c = typeof b === "undefined";
    if (a !== h && c) return a;
    for (var d = {}, b = b || k[B][vb], e = b[p]("?"), f = b[p]("#"), b = (f === -1 ? b[Ya](e + 1) : [b[Ya](e + 1, f - e - 1), "&", b[Ya](f + 1)][K](""))[z]("&"), e = i.dd ? ia : unescape, f = 0, g = b[w]; f < g; ++f) {
        var l = b[f][p]("=");
        if (l !== -1) {
            var q = b[f][I](0, l),
                l = b[f][I](l + 1),
                l = l[Ca](/+/g, " ");
            try {
                d[q] = e(l)
            } catch (A) {}
        }
    }
    c && (a = d);
    return d
}

Está ofuscado, pero es comprensible. No funciona porque algunas variables no están definidas.

Empiezan a buscar parámetros en la URL desde ? y también del hachís #. Luego, para cada parámetro, se dividen en el signo igual. b[f][p]("=") (que se parece a indexOf, utilizan la posición del carácter para obtener la clave / valor). Al dividirlo, comprueban si el parámetro tiene un valor o no, si lo tiene, almacenan el valor de d, de lo contrario, simplemente continúan.

Al final el objeto d se devuelve, manejando el escape y el + firmar. Este objeto es como el mío, tiene el mismo comportamiento.


Mi método como complemento de jQuery

(function($) {
    $.QueryString = (function(paramsArray) {
        let params = {};

        for (let i = 0; i < paramsArray.length; ++i)
        {
            let param = paramsArray[i]
                .split('=', 2);
            
            if (param.length !== 2)
                continue;
            
            params[param[0]] = decodeURIComponent(param[1].replace(/+/g, " "));
        }
            
        return params;
    })(window.location.search.substr(1).split('&'))
})(jQuery);

Uso

//Get a param
$.QueryString.param
//-or-
$.QueryString["param"]
//This outputs something like...
//"val"

//Get all params as object
$.QueryString
//This outputs something like...
//Object { param: "val", param2: "val" }

//Set a param (only in the $.QueryString object, doesn't affect the browser's querystring)
$.QueryString.param = "newvalue"
//This doesn't output anything, it just updates the $.QueryString object

//Convert object into string suitable for url a querystring (Requires jQuery)
$.param($.QueryString)
//This outputs something like...
//"param=newvalue&param2=val"

//Update the url/querystring in the browser's location bar with the $.QueryString object
history.replaceState({}, '', "?" + $.param($.QueryString));
//-or-
history.pushState({}, '', "?" + $.param($.QueryString));

Prueba de rendimiento (método de división contra método de expresiones regulares) (jsPerf)

Código de preparación: declaración de métodos

Código de prueba dividido

var qs = window.GetQueryString(query);

var search = qs["q"];
var value = qs["value"];
var undef = qs["undefinedstring"];

Código de prueba de expresiones regulares

var search = window.getParameterByName("q");
var value = window.getParameterByName("value");
var undef = window.getParameterByName("undefinedstring");

Pruebas en Firefox 4.0 x86 en Windows Server 2008 R2 / 7 x64

  • Método dividido: 144,780 ± 2,17% más rápido
  • Método regex: 13.891 ± 0,85% | 90% más lento
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *