Obtenga valores de url de parámetros de cadena de consulta con jQuery / Javascript (querystring)

149

¿Alguien sabe de una buena manera de escribir una extensión jQuery para manejar parámetros de cadena de consulta? Básicamente quiero extender la ($)función mágica jQuery para poder hacer algo como esto:

$('?search').val(); 

Lo que me daría la "prueba" valor en la siguiente URL: http://www.example.com/index.php?search=test.

He visto muchas funciones que pueden hacer esto en jQuery y Javascript, pero en realidad quiero extender jQuery para que funcione exactamente como se muestra arriba. No estoy buscando un complemento jQuery, estoy buscando una extensión para el método jQuery.

TroySteven
fuente
44
Pregunta y respuesta: stackoverflow.com/questions/901115/…
Nico Westerdale
1
@NicoWesterdale - Revisé ese enlace, pero no vi ninguna respuesta que resolviera esta pregunta en particular. Dijo que quiere exactamente lo anterior.
mrtsherman
2
No creo que pueda hacer esto, una cadena pasada es analizada por sizzler y luego resuelta en una matriz de objetos DOM. Puede extender el comparador para proporcionar filtros personalizados, pero no puede tener un objeto jquery basado en una cadena.
Andrew
66
¿No está $sobrecargado lo suficiente?
Quentin
1
@mrtsherman Mire la función getParameterByName () en el enlace que proporcioné. No, no puede hacerlo directamente desde un indicador $, pero para eso no están los selectores jQuery. Solo está seleccionando parte de una cadena de URL, no está intentando acceder a parte del DOM, que es lo que hace $ (). Es una cosa totalmente diferente. Si realmente quisiera usar jQuery, podría escribir un complemento que usara esta sintaxis: $ .getParameterByName (param), hay un ejemplo más abajo en esa página a la que vinculé que hace exactamente eso. Aunque no tiene sentido.
Nico Westerdale

Respuestas:

46

Después de años de análisis de cadenas feo, hay una mejor manera: URLSearchParams ¡Echemos un vistazo a cómo podemos usar esta nueva API para obtener valores de la ubicación!

// Suponiendo "? Post = 1234 & action = edit"

var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?

post=1234&action=edit&active=1"

ACTUALIZACIÓN: IE no es compatible

use esta función de una respuesta a continuación en lugar de URLSearchParams

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('action')); //edit
Saurin
fuente
1
¿URLSearchParams es compatible con todos los navegadores?
divina el
¡Uy! ohh hombre, IE no es compatible !! Acabo de probarlo. Mientras que Chrome, FF, Safari no tiene ningún problema.
Saurin
1
@divine - Hay un polyfill para URLSearchParams aquí: github.com/WebReflection/url-search-params
Roberto
Si agrega un polyfill para navegadores no compatibles, esta solución URLSearchParams funciona bien. github.com/ungap/url-search-params
Louisvdw
104

¿Por qué extender jQuery? ¿Cuál sería el beneficio de extender jQuery en lugar de tener una función global?

function qs(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
    var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}

http://jsfiddle.net/gilly3/sgxcL/

Un enfoque alternativo sería analizar toda la cadena de consulta y almacenar los valores en un objeto para su uso posterior. Este enfoque no requiere una expresión regular y extiende el window.locationobjeto (pero podría usar fácilmente una variable global):

location.queryString = {};
location.search.substr(1).split("&").forEach(function (pair) {
    if (pair === "") return;
    var parts = pair.split("=");
    location.queryString[parts[0]] = parts[1] &&
        decodeURIComponent(parts[1].replace(/\+/g, " "));
});

http://jsfiddle.net/gilly3/YnCeu/

Esta versión también hace uso de Array.forEach(), que no está disponible de forma nativa en IE7 e IE8. Puede agregarse usando la implementación en MDN , o puede usar jQuery's $.each()en su lugar.

gilly3
fuente
2
No es común, pero es válido usar punto y coma en lugar de símbolos en los parámetros de consulta.
Muhd
@Muhd: es "válido" usar cualquier delimitador que desee en una cadena de consulta siempre que su código lo entienda. Pero, cuando se envía un formulario, los campos del formulario se envían como name=valuepares, separados por &. Si su código usa un formato de cadena de consulta personalizado, obviamente, necesitará escribir un analizador de cadena de consulta personalizado donde sea que se consuma la cadena de consulta, ya sea en el servidor o en el cliente.
gilly3
2
@nick - Interesante. Pero su sugerencia para que los servidores HTTP traten los punto y coma como símbolos de unión solo sirve para hacer que HTML sea más bonito cuando se usa un enlace para imitar el envío de un formulario. Es solo una sugerencia y no es estándar. Un GETenvío de formulario estándar se codifica como application/x-www-form-urlencoded, con valores separados por &. Mi código maneja ese estándar. Las estructuras de URL personalizadas, como la que vinculó, necesitarán un analizador personalizado del lado del servidor y del lado del cliente. De todos modos, agregar esa capacidad a mi código anterior sería trivial.
gilly3
1
@gilly de hecho, si quieres un código portátil, debes admitir ambos
nick
1
Agregue "i" a RegExp () para que la clave no distinga entre mayúsculas y minúsculas: nuevo RegExp ("[? &]" + Key + "= ([^ &] +) (& | $)", "i"));
Yovav
94

El complemento jQuery-URL-Parser de JQuery hace el mismo trabajo, por ejemplo, para recuperar el valor del parámetro de cadena de consulta de búsqueda , puede usar

$.url().param('search');

Esta biblioteca no se mantiene activamente. Según lo sugerido por el autor de la misma plugin, puede utilizar URI.js .

O puede usar js-url en su lugar. Es bastante similar al de abajo.

Para que pueda acceder al parámetro de consulta como $.url('?search')

RameshVel
fuente
2
Agradable. Y el código es de dominio público, por lo que ni siquiera tiene que incluir los comentarios.
Muhd
44
Buena solución, pero no funcionará si está probando a través del archivo: //
kampsj
1
¿Qué tiene que ver con algo? @Kampsj
RameshVel
3
Hola @kampsj, probar con el file://protocolo hará que muchas más cosas no funcionen. Puede crear un servidor HTML estático muy rápido y fácil con node.js. stackoverflow.com/questions/16333790/…
Jess
2
Este complemento ya no se mantiene y el autor mismo sugiere utilizar otros complementos en su lugar.
JanErikGunnar
77

Encontré esta joya de nuestros amigos en SitePoint. https://www.sitepoint.com/url-parameters-jquery/ .

Usando PURE jQuery. Acabo de usar esto y funcionó. Lo ajusté un poco, por ejemplo, el sake.

//URL is http://www.example.com/mypage?ref=registration&[email protected]

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('ref')); //registration
console.log($.urlParam('email')); //[email protected]

Úselo como quiera.

ClosDesign
fuente
Excelente. ¡Gracias! Sin embargo, no creo que necesites la última etiqueta de cierre.
bhtabor
Ahh sí, tienes razón. Editado el post. Eso fue dejado por alguna declaración if en mi código. Gracias.
ClosDesign
1
Debería usar window.location.search en lugar de .href; de lo contrario, bien.
BrainSlugs83
44
En lugar de results[1] || 0hacerlo, debe hacerlo si (resultados) {return results [1]} return 0; Los parámetros de consulta de bcoz pueden no estar presentes en absoluto. Y la modificación manejará todos los casos genéricos.
myDoggyWritesCode
1
¿Qué haces si tienes algo así https://example.com/?c=Order+ID? Ese signo más aún permanece en esta función.
Volomike
47

Este no es mi ejemplo de código, pero lo he usado en el pasado.

//First Add this to extend jQuery

    $.extend({
      getUrlVars: function(){
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for(var i = 0; i < hashes.length; i++)
        {
          hash = hashes[i].split('=');
          vars.push(hash[0]);
          vars[hash[0]] = hash[1];
        }
        return vars;
      },
      getUrlVar: function(name){
        return $.getUrlVars()[name];
      }
    });

    //Second call with this:
    // Get object of URL parameters
    var allVars = $.getUrlVars();

    // Getting URL var by its name
    var byName = $.getUrlVar('name');
Rob Nield
fuente
2
No debe dividirse en '=', técnicamente está bien tener un segundo signo igual en el valor de cualquier par clave / valor. - Solo el primer signo igual que encuentre (por par clave / valor) debe tratarse como un delimitador. (Además, el signo igual no es estrictamente obligatorio; es posible tener una clave sin valor)
BrainSlugs83
Solución limpia Funcionó perfectamente en mi caso.
JF Gagnon
$ .extend ({getUrlVars: function () {var vars = [], hash; var hashes = window.location.href.slice (window.location.href.indexOf ('?') + 1) .split ('& '); for (var i = 0; i <hashes.length; i ++) {hash = hashes [i] .split (' = '); var k = hash.shift (); vars.push (k); vars [k] = hash.join ("");} return vars;}, getUrlVar: function (name) {return $ .getUrlVars () [name];}});
Mupinc
15

Escribí una pequeña función donde solo tienes que analizar el nombre del parámetro de consulta. Entonces, si tiene:? Project = 12 & Mode = 200 & date = 2013-05-27 y desea el parámetro 'Mode', solo tiene que analizar el nombre 'Mode' en la función:

function getParameterByName( name ){
    var regexS = "[\\?&]"+name+"=([^&#]*)", 
  regex = new RegExp( regexS ),
  results = regex.exec( window.location.search );
  if( results == null ){
    return "";
  } else{
    return decodeURIComponent(results[1].replace(/\+/g, " "));
  }
}

// example caller:
var result =  getParameterByName('Mode');
Plippie
fuente
Si su nombre no tiene basura, puede soltar la primera expresión regular y tiene más sentido comenzar desde location.search
mplungjan
7

Sobre la base de la respuesta de @Rob Neild anterior, aquí hay una adaptación JS pura que devuelve un objeto simple de parámetros de cadena de consulta decodificados (sin% 20's, etc.).

function parseQueryString () {
  var parsedParameters = {},
    uriParameters = location.search.substr(1).split('&');

  for (var i = 0; i < uriParameters.length; i++) {
    var parameter = uriParameters[i].split('=');
    parsedParameters[parameter[0]] = decodeURIComponent(parameter[1]);
  }

  return parsedParameters;
}

fuente
No he visto ningún error al usar este código. ¿Qué navegador estás usando? Lo he probado contra Firefox, Chrome y Safari actuales.
Sí, lo siento, lo leí mal. Pensé que lo vi llamar a un método sobre algo que estaba volviendo indefinido. Así que realmente solo se ejecuta una vez cuando no tiene que hacerlo. Cuando la búsqueda es "". Y obtienes {"": "undefined"}
Jerinaw
Si. Eso probablemente podría usar un poco de refinamiento.
1

Escrito en Javascript Vanilla

     //Get URL
     var loc = window.location.href;
     console.log(loc);
     var index = loc.indexOf("?");
     console.log(loc.substr(index+1));
     var splitted = loc.substr(index+1).split('&');
     console.log(splitted);
     var paramObj = [];
     for(var i=0;i<splitted.length;i++){
         var params = splitted[i].split('=');
         var key = params[0];
         var value = params[1];
         var obj = {
             [key] : value
         };
         paramObj.push(obj);
         }
    console.log(paramObj);
    //Loop through paramObj to get all the params in query string.
Prasad varonil
fuente
1
function parseQueryString(queryString) {
    if (!queryString) {
        return false;
    }

    let queries = queryString.split("&"), params = {}, temp;

    for (let i = 0, l = queries.length; i < l; i++) {
        temp = queries[i].split('=');
        if (temp[1] !== '') {
            params[temp[0]] = temp[1];
        }
    }
    return params;
}

Yo uso esto.

donvercety
fuente