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


¿Hay alguna forma de recuperación sin complementos? cadena de consulta valores a través de jQuery (o sin)?

¿Si es así, cómo? Si no, ¿hay un complemento que pueda hacerlo?


2703


origen


Respuestas:


No necesitas jQuery para ese propósito. Puedes usar solo JavaScript puro:

function getParameterByName(name, url) {
    if (!url) 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ás el primer valor (lorem) No existe un estándar sobre esto y los usos varían, vea por ejemplo esta pregunta: Posición autoritativa de claves de consulta HTTP GET duplicadas.
NOTA: La función distingue entre mayúsculas y minúsculas. Si prefiere nombre de parámetro insensible a mayúsculas y minúsculas, agregar el modificador 'i' a RegExp


Esta es una actualización basada en el nuevo Especificaciones de URLSearchParams para lograr el mismo resultado de manera más sucinta. Ver respuesta titulada "URLSearchParams"abajo".


7017



Algunas de las soluciones publicadas aquí son ineficientes. La repetición de la búsqueda de expresión regular cada vez que la secuencia de comandos necesita acceder a un parámetro es completamente innecesaria, 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 HTML 5, esto solo es necesario una vez por carga de página. Las otras sugerencias aquí tampoco pueden 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.ubicación.search.subcadena(1);

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

Ejemplo de cadena de consulta:

?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 cadenas de consulta estilo array también. Un ejemplo de esto es 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 ; o &, que creo que es innecesario porque es raro que ; se usa y yo diría incluso más improbable que ambos sean utilizados. Si necesitas apoyar ; en lugar de &, simplemente cambiarlos 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 puedes escribir:

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

¡Mucho más simple!


1626



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, lo siguiente volverá:

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

Método de Google

Desgarrando 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.

Comienzan a buscar parámetros en la url de ? y también del hash #. Luego, para cada parámetro, se dividen en el signo igual b[f][p]("=") (que se parece a indexOf, usan la posición del char para obtener la clave / valor). Al dividirlo, comprueban si el parámetro tiene un valor o no, si lo tiene, almacenan el valor de dde lo contrario, simplemente continúan.

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


Mi método como un plugin 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 el método de expresión regular) (jsPerf)

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

Código de prueba dividida

var qs = window.GetQueryString(query);

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

Código de prueba Regex

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

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

  • Método de división: 144,780 ± 2,17% más rápido
  • Método Regex: 13,891 ± 0,85% | 90% más lento

1194



Versión mejorada de La respuesta de Artem Barger:

function getParameterByName(name) {
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

Para obtener más información sobre la mejora, consulte: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/


636



URLSearchParams

Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ y Chrome 49+ admiten el URLSearchParams API:

Hay un google-sugirió URLSearchParams polyfill para las versiones estables de IE.

No está estandarizado por W3C, pero es un nivel de vida por WhatWG.

Puede usarlo en el lugar, pero necesita eliminar el ? signo de interrogación (por ejemplo, con .slice(1))

let params = new URLSearchParams(location.search.slice(1));

o

let params = (new URL(location)).searchParams;

O por supuesto en cualquier URL:

let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search.slice(1));

Puedes obtener los params también usando una taquigrafía .searchParams propiedad en el objeto URL, como este:

let params = new URL('https://example.com?foo=1&bar=2').searchParams;
params.get('foo'); // "1"
params.get('bar'); // "2" 

Usted lee / establece parámetros a través del get(KEY), set(KEY, VALUE), append(KEY, VALUE) API. También puede iterar sobre todos los valores for (let p of params) {}.

UN Implementación de referencia y un Página de Ejemplo están disponibles para auditar y probar.


482



Solo otra recomendación. El complemento Puntilla permite recuperar todas las partes de la URL, incluido el anclaje, el host, etc.

Se puede usar con o sin jQuery.

El uso es muy simple y genial:

var url = $.url('http://allmarkedup.com/folder/dir/index.html?item=value'); // jQuery version
var url = purl('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.attr('protocol'); // returns 'http'
url.attr('path'); // returns '/folder/dir/index.html'

Sin embargo, a partir del 11 de noviembre de 2014, Purl ya no se mantiene y el autor recomienda usar URI.js en lugar. El plugin jQuery es diferente porque se enfoca en elementos: para usar con cadenas, solo use URI directamente, con o sin jQuery. Un código similar se vería así, documentos más completos aquí:

var url = new URI('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.protocol(); // returns 'http'
url.path(); // returns '/folder/dir/index.html'

394



Roshambo en snipplr.com tiene un script simple para lograr esto descrito en Obtenga los parámetros de URL con jQuery | Mejorado. Con su script también puede sacar fácilmente los parámetros que desee.

Aquí está la esencia:

$.urlParam = function(name, url) {
    if (!url) {
     url = window.location.href;
    }
    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
    if (!results) { 
        return undefined;
    }
    return results[1] || undefined;
}

Luego solo obtenga sus parámetros de la cadena de consulta.

Entonces, si la cadena URL / consulta era xyz.com/index.html?lang=de.

Solo llama var langval = $.urlParam('lang');y lo tienes.

UZBEKJON también tiene una excelente publicación en el blog sobre esto, Obtenga los parámetros y valores de URL con jQuery.


215



tl; dr

Un rápido, solución completa, que maneja llaves multivaluadas y caracteres codificados.

var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (qd[k] = qd[k] || []).push(v)})

//using ES6   (23 characters cooler)
var qd = {};
if (location.search) location.search.substr(1).split`&`.forEach(item => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v)})
Multi-alineado:
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {
    var s = item.split("="),
        k = s[0],
        v = s[1] && decodeURIComponent(s[1]); //  null-coalescing / short-circuit
    //(k in qd) ? qd[k].push(v) : qd[k] = [v]
    (qd[k] = qd[k] || []).push(v) // null-coalescing / short-circuit
})

¿Qué es todo este código ...
"nulo-coalescente", evaluación de cortocircuito
ES6 Destrucciones de asignaciones, Funciones de flecha, Cadenas de plantillas

Ejemplo:
"?a=1&b=0&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

> qd.a[1]    // "5"
> qd["a"][1] // "5"



Leer más ... sobre la solución JavaScript de Vanilla.

Para acceder a diferentes partes de un uso de URL location.(search|hash)

La solución más fácil (ficticia)

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • Manijas llaves vacías correctamente.
  • Sobrescribe llaves múltiples con último valor encontrado.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

Teclas multivaluadas

Verificación de llave simple (item in dict) ? dict.item.push(val) : dict.item = [val]

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {(item.split("=")[0] in qd) ? qd[item.split("=")[0]].push(item.split("=")[1]) : qd[item.split("=")[0]] = [item.split("=")[1]]})
  • Ahora regresa matrices en lugar.
  • Acceda a los valores por qd.key[index] o qd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

¿Personajes codificados?

Utilizar decodeURIComponent() para el segundo o ambos se divide.

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var k = item.split("=")[0], v = decodeURIComponent(item.split("=")[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
Ejemplo:
"?a=1&b=0&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: ["undefined"]  // decodeURIComponent(undefined) returns "undefined" !!!*
e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]



De los comentarios

* !!! Tenga en cuenta que decodeURIComponent(undefined) devuelve cadena "undefined". La solución radica en un simple uso de &&, lo que asegura que decodeURIComponent() no se llama en valores indefinidos (Consulte la "solución completa" en la parte superior).

v = v && decodeURIComponent(v);


Si la cadena de consulta está vacía (location.search == ""), el resultado es algo engañoso qd == {"": undefined}. Se sugiere verificar la cadena de consulta antes de iniciar la función de análisis likeso:

if (location.search) location.search.substr(1).split("&").forEach(...)

215



Si está utilizando jQuery, puede usar una biblioteca, como jQuery BBQ: botón Atrás y biblioteca de consultas.

... jQuery BBQ proporciona un completo .deparam() método, junto con la administración del estado de hash, y los métodos de utilidad de fusión y análisis de cadenas de fragmentos / consultas.

Editar: Agregar ejemplo de Deparam:

 var DeparamExample = function() {
            var params = $.deparam.querystring();

            //nameofparam is the name of a param from url
            //code below will get param if ajax refresh with hash
            if (typeof params.nameofparam == 'undefined') {
                params = jQuery.deparam.fragment(window.location.href);
            }
            
            if (typeof params.nameofparam != 'undefined') {
                var paramValue = params.nameofparam.toString();
                  
            }
        };

Si solo quieres usar JavaScript, puedes usar ...

var getParamValue = (function() {
    var params;
    var resetParams = function() {
            var query = window.location.search;
            var regex = /[?&;](.+?)=([^&;]+)/g;
            var match;

            params = {};

            if (query) {
                while (match = regex.exec(query)) {
                    params[match[1]] = decodeURIComponent(match[2]);
                }
            }    
        };

    window.addEventListener
    && window.addEventListener('popstate', resetParams);

    resetParams();

    return function(param) {
        return params.hasOwnProperty(param) ? params[param] : null;
    }

})();​

Debido a la nueva API de historial de HTML y específicamente history.pushState() y history.replaceState(), la URL puede cambiar lo que invalidará la caché de parámetros y sus valores.

Esta versión actualizará su caché interna de parámetros cada vez que cambie el historial.


164



Solo usa dos splits:

function get(n) {
    var half = location.search.split(n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

Estaba leyendo todas las respuestas anteriores y más completas. Pero creo que ese es el método más simple y rápido. Puedes verificar en este jsPerf punto de referencia

Para resolver el problema en el comentario de Rup, agregue una división condicional cambiando la primera línea a las dos a continuación. Pero la precisión absoluta significa que ahora es más lento que la expresión regular (ver jsPerf)

function get(n) {
    var half = location.search.split('&' + n + '=')[1];
    if (!half) half = location.search.split('?' + n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

Entonces, si sabes que no te encontrarás con el contra-caso de Rup, esto gana. De lo contrario, regexp.

O si tiene control de la cadena de consulta y puede garantizar que un valor que está tratando de obtener nunca contenga ninguna URL codificada   caracteres (tener estos en un valor sería una mala idea) - puede usar   la siguiente versión ligeramente más simplificada y legible de la primera opción:

    function getQueryStringValueByName(name) {
        var queryStringFromStartOfValue = location.search.split(name + '=')[1];
         return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;

95