¿Cómo puedo agregar o actualizar un parámetro de cadena de consulta?

364

Con javascript, ¿cómo puedo agregar un parámetro de cadena de consulta a la url si no está presente o si está presente, actualizar el valor actual? Estoy usando jquery para mi desarrollo del lado del cliente.

aficionado
fuente
1
Parece que he escrito la función "parseQueryString" en JavaScript unas 100 veces a lo largo de mi carrera. No es dificil. Puntos clave, String#splittoma un segundo parámetro para divisiones máximas. jQuery maptambién será útil.
jpsimons
Esta publicación SO también tiene muchas soluciones stackoverflow.com/questions/1090948/…
Dilip Rajkumar
1
Algunas personas toman esta pregunta como "cómo cambiar la URL en la barra de direcciones" y otras "cómo cambiar cualquier variable de URL"
PandaWood
posible duplicado de stackoverflow.com/questions/486896/…
Usuario

Respuestas:

468

Escribí la siguiente función que logra lo que quiero lograr:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  }
  else {
    return uri + separator + key + "=" + value;
  }
}
aficionado
fuente
36
Esta respuesta no funciona cuando hay un hash en el URI: las cadenas de consulta deben colocarse antes del hash, de lo contrario no se enviarán al servidor. jsfiddle.net/4yXzR
Greg
20
[?|&]debería ser[?&]
soju
8
Limite el alcance de la variable del separador a la función local agregando varjusto antes de la declaración del separador.
Andrea Salicetti
3
Creo que debería agregar value = encodeURIComponent(value);la primera línea, de lo contrario, los saltos de línea no se escaparán correctamente.
Felix
18
Esto también se encargará del hash: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz
189

He expandido la solución y la combiné con otra que encontré para reemplazar / actualizar / eliminar los parámetros de la cadena de consulta en función de la entrada de los usuarios y teniendo en cuenta el ancla de las URL.

Si no se proporciona un valor, se eliminará el parámetro; si se proporciona uno, se agregará / actualizará el parámetro. Si no se proporciona ninguna URL, se tomará de window.location

function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        } 
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
        else {
            return url;
        }
    }
}

Actualizar

Hubo un error al eliminar el primer parámetro en la cadena de consulta, he reelaborado la expresión regular y la prueba para incluir una solución.

Segunda actualización

Según lo sugerido por @ JarónBarends: ajuste la verificación del valor para verificar los valores indefinidos y nulos para permitir establecer valores 0

Tercera actualización

Hubo un error en el que eliminar una variable de cadena de consulta directamente antes de que un hashtag perdiera el símbolo de hashtag que se ha solucionado

Cuarta actualización

Gracias @rooby por señalar una optimización de expresiones regulares en el primer objeto RegExp. Establezca la expresión regular inicial en ([? &]) Debido a un problema con el uso de (\? | &) Encontrado por @YonatanKarni

Quinta actualización

Eliminar la declaración de hash var en la instrucción if / else

ellemayo
fuente
55
Simplemente verificando la 'veracidad' de valuehará que esto elimine las variables de la cadena de consulta cuando establezca su valor en 0. por lo tanto, en lugar de if (value) {}usarloif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends
1
En el RegExp ([? | &]) Realmente debería ser ([? &])
rooby
Es curioso cómo eso se trasladó de la solución original - también podría usar (\? | &)
ellemayo
1
obteniendo una excepción de "excepción regular inválida / grupo inválido" en la creación de expresiones regulares en la versión 31.0.1650.63 de Chrome, resuelta devolviendo el principio a "([? &])"
Yonatan Karni
1
No es que esto importe, excepto que yo sea TOC, pero la variable hashse declara dos veces;)
wlingke
117

La utilidad URLSearchParams puede ser útil para esto en combinación con window.location.search. Por ejemplo:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search);
    searchParams.set("foo", "bar");
    window.location.search = searchParams.toString();
}

Ahora foose ha configurado barindependientemente de si ya existía o no.

Sin embargo, la asignación anterior window.location.searchcausará una carga de página, por lo que si eso no es conveniente, use la API de historial de la siguiente manera:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search)
    searchParams.set("foo", "bar");
    var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
    history.pushState(null, '', newRelativePathQuery);
}

Ahora no necesita escribir su propia expresión regular o lógica para manejar la posible existencia de cadenas de consulta.

Sin embargo, el soporte del navegador es deficiente ya que actualmente es experimental y solo se usa en versiones recientes de Chrome, Firefox, Safari, iOS Safari, navegador de Android, Android Chrome y Opera. Úselo con un polyfill si decide usarlo.

Actualización: el soporte del navegador ha mejorado desde mi respuesta original.

Anthony Manning-Franklin
fuente
polly fill, no es bueno, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference en ie11 obtienes ese error. no es un pollyfill si no funciona como alternativa.
Val
66
Actualización 2019 : el soporte del navegador ahora es bueno para la mayoría de los navegadores, excepto IE y algunos navegadores móviles pequeños. El nuevo pollyfill de ungap cubre fácilmente eso: github.com/ungap/url-search-params
Flion
Respuesta perfecta, sin embargo, no maneja el caso de uso cuando el hashtag está presente en la url. Simple agregar hash al final de newRelativePathQueryhace el truco:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec
43

Basado en la respuesta de @ amateur (y ahora incorporando la solución del comentario de @j_walker_dev), pero teniendo en cuenta el comentario sobre las etiquetas hash en la url, uso lo siguiente:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
}

Editado para corregir [?|&]en expresiones regulares, que por supuesto debería ser [?&]como se señala en los comentarios

Editar: versión alternativa para admitir la eliminación de parámetros de URL también. He utilizado value === undefinedcomo la forma de indicar la eliminación. Podría usar value === falseo incluso un parámetro de entrada por separado según lo deseado.

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if( value === undefined ) {
    if (uri.match(re)) {
        return uri.replace(re, '$1$2');
    } else {
        return uri;
    }
  } else {
    if (uri.match(re)) {
        return uri.replace(re, '$1' + key + "=" + value + '$2');
    } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
  }  
}

Véalo en acción en https://jsfiddle.net/bp3tmuxh/1/

Adán
fuente
2
Mucho más limpio. FYI para usuarios de enrutadores ui angulares que pueden tener "?" en el hash también Mover la var separatorlínea a la derecha sobre el retorno corrige un error con "/ app # / cool? Fun = true". Esto elegiría un "&" como separador aunque todavía no haya parámetros de cadena de consulta reales. Solo clientes.
j_walker_dev
3
Como se señaló en los comentarios sobre otras respuestas, [?|&]debe ser justo [?&](de lo contrario coincidirá |).
Bonger
1
Si, "([?|&])"no es bueno Por favor arregle esto como var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");o var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(¡una buena extensión de otras maneras!)
YakovL
ok, lo siento, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");no funciona, el segundo sí
YakovL
Parece que esta versión no admite la eliminación de un parámetro de cadena de consulta al omitir el valor. Estoy en lo cierto?
jkupczak
12

Me doy cuenta de que esta pregunta es antigua y ha sido respondida a muerte, pero aquí está mi puñalada. Estoy tratando de reinventar la rueda aquí porque estaba usando la respuesta actualmente aceptada y el mal manejo de los fragmentos de URL recientemente me mordió en un proyecto.

La función está abajo. Es bastante largo, pero fue hecho para ser lo más resistente posible. Me encantaría sugerencias para acortarlo / mejorarlo. Preparé un pequeño conjunto de pruebas jsFiddle para él (u otras funciones similares). Si una función puede pasar cada una de las pruebas allí, digo que probablemente sea bueno ir.

Actualización: Encontré una función genial para usar el DOM para analizar URL , así que incorporé esa técnica aquí. Hace que la función sea más corta y más confiable. Apoyos para el autor de esa función.

/**
 * Add or update a query string parameter. If no URI is given, we use the current
 * window.location.href value for the URI.
 * 
 * Based on the DOM URL parser described here:
 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
 *
 * @param   (string)    uri     Optional: The URI to add or update a parameter in
 * @param   (string)    key     The key to add or update
 * @param   (string)    value   The new value to set for key
 *
 * Tested on Chrome 34, Firefox 29, IE 7 and 11
 */
function update_query_string( uri, key, value ) {

    // Use window URL if no query string is provided
    if ( ! uri ) { uri = window.location.href; }

    // Create a dummy element to parse the URI with
    var a = document.createElement( 'a' ), 

        // match the key, optional square brackets, an equals sign or end of string, the optional value
        reg_ex = new RegExp( key + '((?:\\[[^\\]]*\\])?)(=|$)(.*)' ),

        // Setup some additional variables
        qs,
        qs_len,
        key_found = false;

    // Use the JS API to parse the URI 
    a.href = uri;

    // If the URI doesn't have a query string, add it and return
    if ( ! a.search ) {

        a.search = '?' + key + '=' + value;

        return a.href;
    }

    // Split the query string by ampersands
    qs = a.search.replace( /^\?/, '' ).split( /&(?:amp;)?/ );
    qs_len = qs.length; 

    // Loop through each query string part
    while ( qs_len > 0 ) {

        qs_len--;

        // Remove empty elements to prevent double ampersands
        if ( ! qs[qs_len] ) { qs.splice(qs_len, 1); continue; }

        // Check if the current part matches our key
        if ( reg_ex.test( qs[qs_len] ) ) {

            // Replace the current value
            qs[qs_len] = qs[qs_len].replace( reg_ex, key + '$1' ) + '=' + value;

            key_found = true;
        }
    }   

    // If we haven't replaced any occurrences above, add the new parameter and value
    if ( ! key_found ) { qs.push( key + '=' + value ); }

    // Set the new query string
    a.search = '?' + qs.join( '&' );

    return a.href;
}
Dominic P
fuente
2
Esto se ve muy bien, casos de prueba sólidos + usando el DOM como analizador de URL. Sin embargo, encontré dos casos: example.com/?param=val& => example.com/?param=val&&new=key --double & y example.com/team => example.com/team?new=key esperado: team /? new = key alguna redirección / team? new = key a / team / y las consultas se pierden.
Timar Ivo Batis
1
Gracias por el caso de prueba fallido. Actualicé el violín. El primero es duro. ¿Alguna idea sobre cómo solucionar la función? El segundo debe manejarse sin problemas y ya está cubierto en el conjunto de pruebas. Aunque quizás no te entiendo. Siéntase libre de bifurcar el violín de prueba para demostrar lo que está viendo.
Dominic P
Agregué algunos casos de prueba con los que me encontré y soluciones alternativas. Traté de usar el DOM tanto como sea posible. Principalmente, necesitaba que esto también funcionara para enlaces relativos dentro del mismo dominio. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis
1
@braed Me gusta el enfoque porque deja el trabajo pesado al navegador. Como puede ver en muchas respuestas aquí, este problema no es tan simple como parece. Hay MUCHOS casos de esquina que una solución necesita cubrir. La mayoría de ellos están cubiertos de forma gratuita cuando aprovecha el DOM.
Dominic P
1
@braed seguro, solo eche un vistazo al conjunto de pruebas que vinculé en la respuesta. Muchas de las soluciones aquí que no dependen del DOM fallan porque no tienen en cuenta todos los casos límite enumerados. En cuanto a la lectura, puede ser instructivo mirar el módulo URL para node.js. No está directamente relacionado, pero le da una idea de la complejidad de las cadenas de URL.
Dominic P
11

window.location.search es de lectura / escritura.

Sin embargo, la modificación de la cadena de consulta redirigirá la página en la que se encuentra y generará una actualización del servidor.

Si lo que está intentando hacer es mantener el estado del lado del cliente (y potencialmente hacer que sea compatible con marcadores), querrá modificar el hash de URL en lugar de la cadena de consulta, lo que lo mantiene en la misma página (ventana.ubicación. hash es de lectura / escritura). Así es como los sitios web como twitter.com hacen esto.

También querrá que funcione el botón Atrás, deberá vincular los eventos de JavaScript al evento de cambio de hash, un buen complemento para eso es http://benalman.com/projects/jquery-hashchange-plugin/

Galón
fuente
44
¡Twitter ya no modifica el hash! Hash está muerto, ¡bienvenido a History API !
Alba Mendez
Está lejos de estar muerto. Creo que estás viviendo en un país de ensueño mágico donde la compatibilidad con el navegador heredado no es una preocupación Este puede ser el caso para usted, pero ciertamente no es el caso para el resto de nosotros (o de hecho, la mayoría de nosotros). quizás morir sea ​​más apropiado ...
AaronHS
1
Un año después, parece que el único navegador semi-reciente que no lo admite es IE 9
Douglas
11

Si no está configurado o desea actualizar con un nuevo valor, puede usar:

window.location.search = 'param=value'; // or param=new_value

Esto está en Javascript simple, por cierto.

EDITAR

Es posible que desee intentar usar el complemento jquery query-object

window.location.search = jQuery.query.set ("param", 5);

tradyblix
fuente
1
sin embargo, esto no mantendrá ningún otro parámetro de cadena de consulta en la url.
aficionado
tienes razón, te pido disculpas ... como una actualización, agregué otra opción a mi respuesta :)
tradyblix
Esto no funciona porque no restablece un valor. "agregar o actualizar"
Paolo Falomo
9

Este es mi enfoque: la location.params()función (que se muestra a continuación) se puede usar como getter o setter. Ejemplos:

Dada la URL es http://example.com/?foo=bar&baz#some-hash ,

  1. location.params() devolverá un objeto con todos los parámetros de consulta: {foo: 'bar', baz: true} .
  2. location.params('foo') volverá 'bar' .
  3. location.params({foo: undefined, hello: 'world', test: true}) cambiará la URL a http://example.com/?baz&hello=world&test#some-hash .

Aquí está la params()función, que opcionalmente se puede asignar al window.locationobjeto.

location.params = function(params) {
  var obj = {}, i, parts, len, key, value;

  if (typeof params === 'string') {
    value = location.search.match(new RegExp('[?&]' + params + '=?([^&]*)[&#$]?'));
    return value ? value[1] : undefined;
  }

  var _params = location.search.substr(1).split('&');

  for (i = 0, len = _params.length; i < len; i++) {
    parts = _params[i].split('=');
    if (! parts[0]) {continue;}
    obj[parts[0]] = parts[1] || true;
  }

  if (typeof params !== 'object') {return obj;}

  for (key in params) {
    value = params[key];
    if (typeof value === 'undefined') {
      delete obj[key];
    } else {
      obj[key] = value;
    }
  }

  parts = [];
  for (key in obj) {
    parts.push(key + (obj[key] === true ? '' : '=' + obj[key]));
  }

  location.search = parts.join('&');
};
jake
fuente
6

Esta es mi preferencia y cubre los casos que se me ocurren. ¿Alguien puede pensar en una forma de reducirlo a un solo reemplazo?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}
Adam Leggett
fuente
También falla un buen número de casos de prueba por Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis
5

Sé que esto es bastante antiguo, pero quiero disparar mi versión de trabajo aquí.

function addOrUpdateUrlParam(uri, paramKey, paramVal) {
  var re = new RegExp("([?&])" + paramKey + "=[^&#]*", "i");
  if (re.test(uri)) {
    uri = uri.replace(re, '$1' + paramKey + "=" + paramVal);
  } else {
    var separator = /\?/.test(uri) ? "&" : "?";
    uri = uri + separator + paramKey + "=" + paramVal;
  }
  return uri;
}

jQuery(document).ready(function($) {
  $('#paramKey,#paramValue').on('change', function() {
    if ($('#paramKey').val() != "" && $('#paramValue').val() != "") {
      $('#uri').val(addOrUpdateUrlParam($('#uri').val(), $('#paramKey').val(), $('#paramValue').val()));
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input style="width:100%" type="text" id="uri" value="http://www.example.com/text.php">
<label style="display:block;">paramKey
  <input type="text" id="paramKey">
</label>
<label style="display:block;">paramValue
  <input type="text" id="paramValue">
</label>

NOTA Esta es una versión modificada de @elreimundo

Paolo Falomo
fuente
2

Mi opinión desde aquí (compatible con "use estricto"; en realidad no usa jQuery):

function decodeURIParams(query) {
  if (query == null)
    query = window.location.search;
  if (query[0] == '?')
    query = query.substring(1);

  var params = query.split('&');
  var result = {};
  for (var i = 0; i < params.length; i++) {
    var param = params[i];
    var pos = param.indexOf('=');
    if (pos >= 0) {
        var key = decodeURIComponent(param.substring(0, pos));
        var val = decodeURIComponent(param.substring(pos + 1));
        result[key] = val;
    } else {
        var key = decodeURIComponent(param);
        result[key] = true;
    }
  }
  return result;
}

function encodeURIParams(params, addQuestionMark) {
  var pairs = [];
  for (var key in params) if (params.hasOwnProperty(key)) {
    var value = params[key];
    if (value != null) /* matches null and undefined */ {
      pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value))
    }
  }
  if (pairs.length == 0)
    return '';
  return (addQuestionMark ? '?' : '') + pairs.join('&');
}

//// alternative to $.extend if not using jQuery:
// function mergeObjects(destination, source) {
//   for (var key in source) if (source.hasOwnProperty(key)) {
//     destination[key] = source[key];
//   }
//   return destination;
// }

function navigateWithURIParams(newParams) {
  window.location.search = encodeURIParams($.extend(decodeURIParams(), newParams), true);
}

Ejemplo de uso:

// add/update parameters
navigateWithURIParams({ foo: 'bar', boz: 42 });

// remove parameter
navigateWithURIParams({ foo: null });

// submit the given form by adding/replacing URI parameters (with jQuery)
$('.filter-form').submit(function(e) {
  e.preventDefault();
  navigateWithURIParams(decodeURIParams($(this).serialize()));
});
Andrey Tarantsov
fuente
2

Basado en la respuesta que dio @ellemayo, se me ocurrió la siguiente solución que permite deshabilitar la etiqueta hash si lo desea:

function updateQueryString(key, value, options) {
    if (!options) options = {};

    var url = options.url || location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), hash;

    hash = url.split('#');
    url = hash[0];
    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            url = url.replace(re, '$1' + key + "=" + value + '$2$3');
        } else {
            url = url.replace(re, '$1$3').replace(/(&|\?)$/, '');
        }
    } else if (typeof value !== 'undefined' && value !== null) {
        var separator = url.indexOf('?') !== -1 ? '&' : '?';
        url = url + separator + key + '=' + value;
    }

    if ((typeof options.hash === 'undefined' || options.hash) &&
        typeof hash[1] !== 'undefined' && hash[1] !== null)
        url += '#' + hash[1];
    return url;
}

Llámalo así:

updateQueryString('foo', 'bar', {
    url: 'http://my.example.com#hash',
    hash: false
});

Resultados en:

http://my.example.com?foo=bar
RuubW
fuente
Quibble estilístico: typeof value !== 'undefined' && value !== nulles más explícito, pero value != nullsignifica lo mismo y es más conciso.
eppsilon
2

Aquí hay una versión más corta que se encarga de

  • consulta con o sin un parámetro dado
  • consulta con múltiples valores de parámetros
  • consulta que contiene hash

Código:

var setQueryParameter = function(uri, key, value) {
  var re = new RegExp("([?&])("+ key + "=)[^&#]*", "g");
  if (uri.match(re)) 
    return uri.replace(re, '$1$2' + value);

  // need to add parameter to URI
  var paramString = (uri.indexOf('?') < 0 ? "?" : "&") + key + "=" + value;
  var hashIndex = uri.indexOf('#');
  if (hashIndex < 0)
    return uri + paramString;
  else
    return uri.substring(0, hashIndex) + paramString + uri.substring(hashIndex);
}

La descripción de expresiones regulares se puede encontrar aquí .

NOTA : Esta solución se basa en la respuesta @amateur, pero con muchas mejoras.

MaxZoom
fuente
2

Código que agrega una lista de parámetros a una url existente usando ES6 y jQuery:

class UrlBuilder {
    static appendParametersToUrl(baseUrl, listOfParams) {

        if (jQuery.isEmptyObject(listOfParams)) {
            return baseUrl;
        }

        const newParams = jQuery.param(listOfParams);

        let partsWithHash = baseUrl.split('#');
        let partsWithParams = partsWithHash[0].split('?');

        let previousParams = '?' + ((partsWithParams.length === 2) ? partsWithParams[1] + '&' : '');
        let previousHash = (partsWithHash.length === 2) ? '#' + partsWithHash[1] : '';

        return partsWithParams[0] + previousParams + newParams + previousHash;
    }
}

Donde listOfParams es como

const listOfParams = {
    'name_1': 'value_1',
    'name_2': 'value_2',
    'name_N': 'value_N',
};

Ejemplo de uso:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Pruebas rápidas:

    url = 'http://hello.world';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world

    url = 'http://hello.world#h1';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world#h1

    url = 'http://hello.world';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p1=v1&p2=v2

    url = 'http://hello.world?p0=v0';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2

    url = 'http://hello.world#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
   // Output: http://hello.world?p1=v1&p2=v2#h1

    url = 'http://hello.world?p0=v0#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2#h1
Samuel Vicent
fuente
1

Un enfoque diferente sin usar expresiones regulares . Admite anclajes 'hash' al final de la url, así como múltiples caracteres de signo de interrogación (?). Debería ser un poco más rápido que el enfoque de expresión regular.

function setUrlParameter(url, key, value) {
  var parts = url.split("#", 2), anchor = parts.length > 1 ? "#" + parts[1] : '';
  var query = (url = parts[0]).split("?", 2);
  if (query.length === 1) 
    return url + "?" + key + "=" + value + anchor;

  for (var params = query[query.length - 1].split("&"), i = 0; i < params.length; i++)
    if (params[i].toLowerCase().startsWith(key.toLowerCase() + "="))
      return params[i] = key + "=" + value, query[query.length - 1] = params.join("&"), query.join("?") + anchor;

  return url + "&" + key + "=" + value + anchor
}
cwills
fuente
1

Use esta función para agregar, eliminar y modificar el parámetro de cadena de consulta de la URL basada en jquery

/**
@param String url
@param object param {key: value} query parameter
*/
function modifyURLQuery(url, param){
    var value = {};

    var query = String(url).split('?');

    if (query[1]) {
        var part = query[1].split('&');

        for (i = 0; i < part.length; i++) {
            var data = part[i].split('=');

            if (data[0] && data[1]) {
                value[data[0]] = data[1];
            }
        }
    }

    value = $.extend(value, param);

    // Remove empty value
    for (i in value){
        if(!value[i]){
            delete value[i];
        }
    }

    // Return url with modified parameter
    if(value){
        return query[0] + '?' + $.param(value);
    } else {
        return query[0];
    }
}

Agregar nuevo y modificar el parámetro existente a la URL

var new_url = modifyURLQuery("http://google.com?foo=34", {foo: 50, bar: 45});
// Result: http://google.com?foo=50&bar=45

Eliminar existente

var new_url = modifyURLQuery("http://google.com?foo=50&bar=45", {bar: null});
// Result: http://google.com?foo=50
jay padaliya
fuente
1

Al usar jQuerypodemos hacer lo siguiente

var query_object = $.query_string;
query_object["KEY"] = "VALUE";
var new_url = window.location.pathname + '?'+$.param(query_object)

En variable new_urltendremos nuevos parámetros de consulta.

Referencia: http://api.jquery.com/jquery.param/

anjaneyulubatta505
fuente
0

Para dar un código de ejemplo para modificar window.location.searchcomo lo sugieren Gal y tradyblix:

var qs = window.location.search || "?";
var param = key + "=" + value; // remember to URI encode your parameters
if (qs.length > 1) {
    // more than just the question mark, so append with ampersand
    qs = qs + "&";
}
qs = qs + param;
window.location.search = qs;
Risadinha
fuente
0

Código de script Java para encontrar una cadena de consulta específica y reemplazar su valor *

('input.letter').click(function () {
                //0- prepare values
                var qsTargeted = 'letter=' + this.value; //"letter=A";
                var windowUrl = '';
                var qskey = qsTargeted.split('=')[0];
                var qsvalue = qsTargeted.split('=')[1];
                //1- get row url
                var originalURL = window.location.href;
                //2- get query string part, and url
                if (originalURL.split('?').length > 1) //qs is exists
                {
                    windowUrl = originalURL.split('?')[0];
                    var qs = originalURL.split('?')[1];
                    //3- get list of query strings
                    var qsArray = qs.split('&');
                    var flag = false;
                    //4- try to find query string key
                    for (var i = 0; i < qsArray.length; i++) {
                        if (qsArray[i].split('=').length > 0) {
                            if (qskey == qsArray[i].split('=')[0]) {
                                //exists key
                                qsArray[i] = qskey + '=' + qsvalue;
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (!flag)//   //5- if exists modify,else add
                    {
                        qsArray.push(qsTargeted);
                    }
                    var finalQs = qsArray.join('&');
                    //6- prepare final url
                    window.location = windowUrl + '?' + finalQs;
                }
                else {
                    //6- prepare final url
                    //add query string
                    window.location = originalURL + '?' + qsTargeted;
                }
            })
        });
Mohamed.Abdo
fuente
0

Sí, tuve un problema en el que mi cadena de consulta se desbordaría y duplicaría, pero esto se debió a mi propia lentitud. así que jugué un poco y trabajé un poco de js jquery (realmente chisporroteo) y magia de C #.

Entonces me di cuenta de que después de que el servidor haya terminado con los valores pasados, los valores ya no importan, no hay reutilización, si el cliente quería hacer lo mismo, evidentemente, siempre será una nueva solicitud, incluso si es el Se pasan los mismos parámetros. Y eso es todo del lado del cliente, por lo que algunos caché / cookies, etc. podrían ser geniales en ese sentido.

JS:

$(document).ready(function () {
            $('#ser').click(function () {
                SerializeIT();
            });
            function SerializeIT() {
                var baseUrl = "";
                baseUrl = getBaseUrlFromBrowserUrl(window.location.toString());
                var myQueryString = "";
                funkyMethodChangingStuff(); //whatever else before serializing and creating the querystring
                myQueryString = $('#fr2').serialize();
                window.location.replace(baseUrl + "?" + myQueryString);
            }
            function getBaseUrlFromBrowserUrl(szurl) {
                return szurl.split("?")[0];
            } 
            function funkyMethodChangingStuff(){
               //do stuff to whatever is in fr2
            }
        });

HTML:

<div id="fr2">
   <input type="text" name="qURL" value="http://somewhere.com" />
   <input type="text" name="qSPart" value="someSearchPattern" />
</div>
<button id="ser">Serialize! and go play with the server.</button>

C#:

    using System.Web;
    using System.Text;
    using System.Collections.Specialized;

    public partial class SomeCoolWebApp : System.Web.UI.Page
    {
        string weburl = string.Empty;
        string partName = string.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            string loadurl = HttpContext.Current.Request.RawUrl;
            string querySZ = null;
            int isQuery = loadurl.IndexOf('?');
            if (isQuery == -1) { 
                //If There Was no Query
            }
            else if (isQuery >= 1) {
                querySZ = (isQuery < loadurl.Length - 1) ? loadurl.Substring(isQuery + 1) : string.Empty;
                string[] getSingleQuery = querySZ.Split('?');
                querySZ = getSingleQuery[0];

                NameValueCollection qs = null;
                qs = HttpUtility.ParseQueryString(querySZ);

                weburl = qs["qURL"];
                partName = qs["qSPart"];
                //call some great method thisPageRocks(weburl,partName); or whatever.
          }
      }
  }

Bien, las críticas son bienvenidas (esta fue una mezcla nocturna, así que siéntete libre de notar los ajustes). Si esto ayudó en algo, pulgar hacia arriba, Happy Coding.

Sin duplicados, cada solicitud es tan única como la modificó, y debido a cómo está estructurada, es fácil agregar más consultas dinámicamente desde el dom.

LokizFenrir
fuente
0

Aquí hay un método alternativo que utiliza las propiedades incorporadas del elemento HTML de anclaje:

  • Maneja parámetros de valores múltiples.
  • No hay riesgo de modificar el fragmento #, o cualquier otra cosa que no sea la cadena de consulta en sí.
  • Puede ser un poco más fácil de leer? Pero es más largo.

    var a = document.createElement('a'),

	getHrefWithUpdatedQueryString = function(param, value) {
	    return updatedQueryString(window.location.href, param, value);
	},

	updatedQueryString = function(url, param, value) {
	    /*
	     A function which modifies the query string 
             by setting one parameter to a single value.

	     Any other instances of parameter will be removed/replaced.
	     */
	    var fragment = encodeURIComponent(param) + 
                           '=' + encodeURIComponent(value);

	    a.href = url;

	    if (a.search.length === 0) {
		a.search = '?' + fragment;
	    } else {
		var didReplace = false,
		    // Remove leading '?'
		    parts = a.search.substring(1)
		// Break into pieces
			.split('&'),

		    reassemble = [],
		    len = parts.length;

		for (var i = 0; i < len; i++) {
		    
		    var pieces = parts[i].split('=');
		    if (pieces[0] === param) {
			if (!didReplace) {
			    reassemble.push('&' + fragment);
			    didReplace = true;
			}
		    } else {
			reassemble.push(parts[i]);
		    }
		}

		if (!didReplace) {
		    reassemble.push('&' + fragment);
		}

		a.search = reassemble.join('&');
	    }

	    return a.href;
	};

GlennS
fuente
0

si desea establecer múltiples parámetros a la vez:

function updateQueryStringParameters(uri, params) {
    for(key in params){
      var value = params[key],
          re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"),
          separator = uri.indexOf('?') !== -1 ? "&" : "?";
      if (uri.match(re)) {
        uri = uri.replace(re, '$1' + key + "=" + value + '$2');
      }
      else {
        uri = uri + separator + key + "=" + value;
      }
    }
    return uri;
}

misma función que la de @ amateur

si jslint le da un error, agregue esto después del ciclo for

if(params.hasOwnProperty(key))
Rachid O
fuente
No maneja hashes, o los parámetros no tienen asignado un valor ( http://abc.def/?a&b&c).
Adam Leggett
0

Hay muchas respuestas incómodas e innecesariamente complicadas en esta página. El mejor clasificado, @ amateur's, es bastante bueno, aunque tiene un poco de pelusa innecesaria en el RegExp. Aquí hay una solución un poco más óptima con RegExp más limpio y una replacellamada más limpia :

function updateQueryStringParamsNoHash(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&]*", "i");
  return re.test(uri)
       ? uri.replace(re, '$1' + key + "=" + value)
       : uri + separator + key + "=" + value
  ;
}

Como una ventaja adicional, si urino es una cadena, no recibirá errores por intentar llamar matchoreplace por algo que puede no implementar esos métodos.

Y si desea manejar el caso de un hash (y ya ha realizado una verificación para HTML correctamente formateado), puede aprovechar la función existente en lugar de escribir una nueva función que contenga la misma lógica:

function updateQueryStringParams(url, key, value) {
    var splitURL = url.split('#');
    var hash = splitURL[1];
    var uri = updateQueryStringParamsNoHash(splitURL[0]);
    return hash == null ? uri : uri + '#' + hash;
}

O puede hacer algunos cambios leves a la excelente respuesta de @ Adam:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&#]*", "i");
  if (re.test(uri)) {
    return uri.replace(re, '$1' + key + "=" + value);
  } else {
    var matchData = uri.match(/^([^#]*)(#.*)?$/);
    var separator = /\?/.test(uri) ? "&" : "?";    
    return matchData[0] + separator + key + "=" + value + (matchData[1] || '');
  }
}
elreimundo
fuente
2
Este es un paréntesis faltante en la última función: var matchData = uri.match (/^([^#font>*)(#.*)?$/
Jammer
separatorno está definido en updateQueryStringParamsNoHash. En updateQueryStringParameter, todo se descompone si el parámetro que está reemplazando no tiene asignado un valor (por ejemplo http://abc.def/?a&b&c).
Adam Leggett
0

Esto debería servir para el propósito:

function updateQueryString(url, key, value) {
    var arr =  url.split("#");
    var url = arr[0];
    var fragmentId = arr[1];
    var updatedQS = "";
    if (url.indexOf("?") == -1) {
        updatedQS = encodeURIComponent(key) + "=" + encodeURIComponent(value);
    }
    else {
        updatedQS = addOrModifyQS(url.substring(url.indexOf("?") + 1), key, value); 
    }
    url = url.substring(0, url.indexOf("?")) + "?" + updatedQS;
    if (typeof fragmentId !== 'undefined') {
        url = url + "#" + fragmentId;
    }
    return url;
}

function addOrModifyQS(queryStrings, key, value) {
    var oldQueryStrings = queryStrings.split("&");
    var newQueryStrings = new Array();
    var isNewKey = true;
    for (var i in oldQueryStrings) {
        var currItem = oldQueryStrings[i];
        var searchKey = key + "=";
        if (currItem.indexOf(searchKey) != -1) {
            currItem = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            isNewKey = false;
        }
        newQueryStrings.push(currItem);
    }
    if (isNewKey) {
        newQueryStrings.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
    }
    return newQueryStrings.join("&");
}   
mmuzahid
fuente