Agregar un parámetro a la URL con JavaScript

276

En una aplicación web que utiliza llamadas AJAX, necesito enviar una solicitud pero agregar un parámetro al final de la URL, por ejemplo:

URL original:

http: //server/myapp.php? id = 10

URL resultante:

http: //server/myapp.php? id = 10 & enabled = true

Buscando una función de JavaScript que analice la URL mirando cada parámetro, luego agrega el nuevo parámetro o actualiza el valor si ya existe uno.

Lessan Vaezi
fuente
¿Has buscado los analizadores de URL de JavaScript ? Podrías hacer el tuyo, dividiéndote en cada carácter, pero probablemente sea más fácil usar el código existente.
csl
1
Tenía un escenario similar una vez y me encontré con este artículo de Peter Bromberg muy útiles:
Cerebrus
2
window.history.pushState ('página2', 'Título', document.location + '/ page2.php'); hará tu trabajo sin cargar la página
Rutunj sheladiya
1
Esta pregunta tiene mejores respuestas aquí stackoverflow.com/questions/6953944/…
rkb
increíble no es nativo en este idioma pobre que JS es ...
bohr

Respuestas:

192

Una implementación básica que deberá adaptar se vería así:

function insertParam(key, value) {
    key = encodeURIComponent(key);
    value = encodeURIComponent(value);

    // kvp looks like ['key1=value1', 'key2=value2', ...]
    var kvp = document.location.search.substr(1).split('&');
    let i=0;

    for(; i<kvp.length; i++){
        if (kvp[i].startsWith(key + '=')) {
            let pair = kvp[i].split('=');
            pair[1] = value;
            kvp[i] = pair.join('=');
            break;
        }
    }

    if(i >= kvp.length){
        kvp[kvp.length] = [key,value].join('=');
    }

    // can return this or...
    let params = kvp.join('&');

    // reload page with new params
    document.location.search = params;
}

Esto es aproximadamente el doble de rápido que una expresión regular o una solución basada en la búsqueda, pero eso depende completamente de la longitud de la cadena de consulta y el índice de cualquier coincidencia


El método de expresión regular lenta que comparé con el de las terminaciones (aprox. + 150% más lento)

function insertParam2(key,value)
{
    key = encodeURIComponent(key); value = encodeURIComponent(value);

    var s = document.location.search;
    var kvp = key+"="+value;

    var r = new RegExp("(&|\\?)"+key+"=[^\&]*");

    s = s.replace(r,"$1"+kvp);

    if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};

    //again, do what you will here
    document.location.search = s;
}
annakata
fuente
2
gracias de nuevo. ver lessanvaezi.com/wp-content/uploads/2009/01/test.html para una comparación básica de los métodos
Lessan Vaezi
16
Usar escape () para escapar de los parámetros de URL es incorrecto. Se rompe para valores con "+" en ellos. Debería usar encodeURIComponent en su lugar. Discusión completa: xkr.us/articles/javascript/encode-compare
Antonin Hildebrand
44
Estoy llamando a esta función y la página se está recargando en bucle infinito. ¡Por favor ayuda!
sumitir
66
cuando ya no hay parámetros en la URL, obtienes un? & param = value
Roy Toledo
9
¿No deberías estar usando en encodeURIComponentlugar de encodeURI? De lo contrario, cualquier carácter como =, &en su nombre o valor, dañará el URI.
Adrian Pronk
271

Puedes usar uno de estos:

Ejemplo:

var url = new URL("http://foo.bar/?x=1&y=2");

// If your expected result is "http://foo.bar/?x=1&y=2&x=42"
url.searchParams.append('x', 42);

// If your expected result is "http://foo.bar/?x=42&y=2"
url.searchParams.set('x', 42);
Vianney Bajart
fuente
2
Me gustaría agregar un parámetro de consulta sin un valor, por ejemplo, agregar XMLpara http://foo.bar/?x=1&y=2que el resultado final sea http://foo.bar/?x=1&y=2&XML. es posible? Lo intenté url.searchParams.set('XML');, url.searchParams.set('XML', null);y url.searchParams.set('XML', undefined);- pero ninguno funcionó en Chrome 63 .
Abdull
2
¡Gracias! Lástima que aún no sea compatible con iOS. developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
kanji
27
Lástima que IE no lo admita.
Spedy
3
iOS ahora admite URLSearchParams (desde 9 días después del comentario de
@kanji
8
¡Buenas noticias @MJeffryes! Todavía no es compatible con IE y Netscape.
Vianney Bajart
64

Gracias a todos por su contribución. Solía annakata código y modifica para incluir también el caso en que no hay ninguna cadena de consulta en la url en absoluto. Espero que esto ayude.

function insertParam(key, value) {
        key = escape(key); value = escape(value);

        var kvp = document.location.search.substr(1).split('&');
        if (kvp == '') {
            document.location.search = '?' + key + '=' + value;
        }
        else {

            var i = kvp.length; var x; while (i--) {
                x = kvp[i].split('=');

                if (x[0] == key) {
                    x[1] = value;
                    kvp[i] = x.join('=');
                    break;
                }
            }

            if (i < 0) { kvp[kvp.length] = [key, value].join('='); }

            //this will reload the page, it's likely better to store this until finished
            document.location.search = kvp.join('&');
        }
    }
Mehdi
fuente
3
Sería mejor al cambio de escape(key)y escape(value)para encodeURIComponentla función.
kolobok
55
¿debería esto realmente comprobar if (kvp.length==1 && kvp[0]="")?
Charles L.
@CharlesL. mejor esif (document.location.search)
Lyubimov Roman
58

Esta es una solución muy simple. No controla la existencia de parámetros y no cambia el valor existente. Agrega su parámetro al final, para que pueda obtener el último valor en su código de fondo.

function addParameterToURL(param){
    _url = location.href;
    _url += (_url.split('?')[1] ? '&':'?') + param;
    return _url;
}
Mehmet Fatih Yıldız
fuente
66
también debe tener en cuenta "#" en la url. Aquí hay algunos url = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+part+"&"+url.split("?")[1] : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+part+"#"+ url.split("#")[1] : url+'?'+part));
errores de
2
@kanzure, esta cosa se ve malvada como el infierno, pero es exactamente lo que quería. Gracias.
Chad von Nau
¿Por qué dividir la url para verificar la existencia de un solo personaje? tampoco olvides codificar ... algo más comofunction appendQs(url, key, value) { return url + (url.indexOf('?') >= 0 ? "&" : '?') + encodeURIComponent(key) + "=" + encodeURIComponent(value); };
drzaus
1
Arreglalo. Esta función no verifica si el parámetro ya está suministrado. Probé esto y lo conseguí https://localhost/preview/inventory.html?sortci=priceASC&sortci=priceASC&sortci=stitle.
Jay
@ Jay, ¿por qué necesita arreglarse? Comprueba tus suposiciones. Los parámetros de cadena de consulta duplicados son legales, lo mismo que los campos de formulario duplicados. Así es como se implementan las listas de casillas de verificación. En HTML y se pasarán a través de una cadena de consulta si el método de formulario = get.
Stephen
34

Aquí hay una versión muy simplificada, que hace concesiones por la legibilidad y menos líneas de código en lugar de un rendimiento micro optimizado (y estamos hablando de una diferencia de unos pocos milisegundos, de manera realista ... debido a la naturaleza de esto (operando en la ubicación del documento actual) ), lo más probable es que se ejecute una vez en una página).

/**
* Add a URL parameter (or changing it if it already exists)
* @param {search} string  this is typically document.location.search
* @param {key}    string  the key to set
* @param {val}    string  value 
*/
var addUrlParam = function(search, key, val){
  var newParam = key + '=' + val,
      params = '?' + newParam;

  // If the "search" string exists, then build params from it
  if (search) {
    // Try to replace an existance instance
    params = search.replace(new RegExp('([?&])' + key + '[^&]*'), '$1' + newParam);

    // If nothing was replaced, then add the new param to the end
    if (params === search) {
      params += '&' + newParam;
    }
  }

  return params;
};

Entonces usarías esto así:

document.location.pathname + addUrlParam(document.location.search, 'foo', 'bar');
Garrett
fuente
1
+1 Me gusta cómo puede especificar algo que no sea document.location.search
Muhd
1
+1 Impresionante, estoy de acuerdo en que la legibilidad es más importante que la microoptimización en este caso y me alegra ver que alguien tomó ese enfoque. @Muhd Quizás fue un error en el motor JS cuando escribiste ese comentario, pero acabo de probar '$ 1' en este contexto y funciona bien.
JMTyler
Muchas gracias por la solución, aunque también me atasco si quiero reemplazar un valor y ya hay un parámetro allí. En cambio, a & escribe $ 1
Codebryo
2
Garrett: ¿Podría arreglar su respuesta para que reemplace los parámetros existentes correctamente? Es sólo una cuestión de reemplazar [\?&]con ([\?&])en la expresión regular (que acababa de editar yo mismo, pero no estoy seguro de si la política comunitaria permite corregir errores en las respuestas).
opyh
Esto no funciona con url como " domain.tld ", agrega "&" en lugar de "?"
user706420
20

/**
* Add a URL parameter 
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var a = document.createElement('a');
   param += (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   a.search += (a.search ? "&" : "") + param;
   return a.href;
}

/**
* Add a URL parameter (or modify if already exists)
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addOrReplaceParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var r = "([&?]|&amp;)" + param + "\\b(?:=(?:[^&#]*))*";
   var a = document.createElement('a');
   var regex = new RegExp(r);
   var str = param + (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   var q = a.search.replace(regex, "$1"+str);
   if (q === a.search) {
      a.search += (a.search ? "&" : "") + str;
   } else {
      a.search = q;
   }
   return a.href;
}

url = "http://www.example.com#hashme";
newurl = addParam(url, "ciao", "1");
alert(newurl);

Y tenga en cuenta que los parámetros deben codificarse antes de agregarse en la cadena de consulta.

http://jsfiddle.net/48z7z4kx/

freedev
fuente
Pequeña pérdida de memoria: querrá eliminar el elemento de anclaje que se agregó al documento antes de regresar.
cáñamo
@freedev, No, no estoy seguro. ;) Me está costando encontrar una fuente autorizada, pero la evidencia sugiere que está en lo correcto. Dado que el elemento creado nunca se adjunta al DOM, debe limpiarse una vez que la variable sale del alcance. La API DOM no está particularmente bien diseñada cuando se trata de efectos secundarios, por lo que soy demasiado cauteloso.
cáñamo
Esta solución agrega una barra diagonal a las URL que no tienen ruta y reordena los parámetros, que son cambios innecesarios y posiblemente indeseables. También agrega en lugar de reemplazar los parámetros existentes que no tienen valor (por ejemplo http://abc.def/?a&b&b).
Adam Leggett
@AdamLeggett Gracias por señalar el error que ocurre cuando un parámetro de solicitud no tiene valor, acabo de corregir mi respuesta. Los comportamientos extraños restantes de los que está hablando, si tiene razón, son generados por un objeto de anclaje HTML que generalmente es un componente estándar del navegador. Sugiero verificar dos veces porque es muy poco probable que un navegador agregue comportamientos innecesarios o indeseables.
freedev
1
El propósito de la función addParam es de hecho agregar varias veces un parámetro, y tal vez debería saber que puede pasar el mismo parámetro incluso con el mismo valor varias veces. stackoverflow.com/questions/24059773/…
freedev
20
const urlParams = new URLSearchParams(window.location.search);

urlParams.set('order', 'date');

window.location.search = urlParams;

.set primer grupo es la clave, el segundo es el valor.

Zoidbergseasharp
fuente
1
Me encanta la simplicidad de esto y que utiliza métodos de navegador nativos
Juan Solano
2
Esta es la respuesta correcta y debe ser votada como la mejor. Esta nueva API es la definitiva para el procesamiento de URL
Anthony,
19

Tengo una 'clase' que hace esto y aquí está:

function QS(){
    this.qs = {};
    var s = location.search.replace( /^\?|#.*$/g, '' );
    if( s ) {
        var qsParts = s.split('&');
        var i, nv;
        for (i = 0; i < qsParts.length; i++) {
            nv = qsParts[i].split('=');
            this.qs[nv[0]] = nv[1];
        }
    }
}

QS.prototype.add = function( name, value ) {
    if( arguments.length == 1 && arguments[0].constructor == Object ) {
        this.addMany( arguments[0] );
        return;
    }
    this.qs[name] = value;
}

QS.prototype.addMany = function( newValues ) {
    for( nv in newValues ) {
        this.qs[nv] = newValues[nv];
    }
}

QS.prototype.remove = function( name ) {
    if( arguments.length == 1 && arguments[0].constructor == Array ) {
        this.removeMany( arguments[0] );
        return;
    }
    delete this.qs[name];
}

QS.prototype.removeMany = function( deleteNames ) {
    var i;
    for( i = 0; i < deleteNames.length; i++ ) {
        delete this.qs[deleteNames[i]];
    }
}

QS.prototype.getQueryString = function() {
    var nv, q = [];
    for( nv in this.qs ) {
        q[q.length] = nv+'='+this.qs[nv];
    }
    return q.join( '&' );
}

QS.prototype.toString = QS.prototype.getQueryString;

//examples
//instantiation
var qs = new QS;
alert( qs );

//add a sinle name/value
qs.add( 'new', 'true' );
alert( qs );

//add multiple key/values
qs.add( { x: 'X', y: 'Y' } );
alert( qs );

//remove single key
qs.remove( 'new' )
alert( qs );

//remove multiple keys
qs.remove( ['x', 'bogus'] )
alert( qs );

He anulado el método toString, por lo que no es necesario llamar a QS :: getQueryString, puede usar QS :: toString o, como lo he hecho en los ejemplos, simplemente confiar en que el objeto se coaccione en una cadena.

meouw
fuente
8

Si tiene una cadena con url que desea decorar con un parámetro, puede intentar esto:

urlstring += ( urlstring.match( /[\?]/g ) ? '&' : '?' ) + 'param=value';

Esto significa que ? será el prefijo del parámetro, pero si ya lo tienes ? en urlstring, que & será el prefijo.

También recomendaría hacerlo encodeURI( paramvariable )si no codificó el parámetro, pero está dentro de a paramvariable; o si tienes personajes divertidos.

Ver codificación de URL de JavaScript para el uso de la encodeURIfunción.

Sasa
fuente
7

Esta es una manera simple de agregar un parámetro de consulta:

const query = new URLSearchParams(window.location.search);
query.append("enabled", "true");

Y eso es todo más aquí .

Tenga en cuenta las especificaciones de soporte .

T04435
fuente
44
Parece que esto no es compatible con ninguna versión de Internet Explorer
MAXE
Ideal para móviles. Cuando aparezca Internet Explorer en mi dispositivo móvil, lo tiraré. :-)
stillatmylinux
@MAXE tienes razón IE / EDGE no soporta mucho.
Admitido
6

Echa un vistazo a https://github.com/derek-watson/jsUri

Uri y manipulación de cadenas de consulta en javascript.

Este proyecto incorpora la excelente biblioteca de expresión regular parseUri de Steven Levithan. Puede analizar de forma segura las URL de todas las formas y tamaños, sin importar si son inválidas u horribles.

Charlie Liang Yuan
fuente
404 - La URL solicitada / p / jsuri / no se encontró en este servidor. Eso es todo lo que sabemos.
Aligma
1
Parece que se ha movido. He actualizado la url. ¡La mejor de las suertes!
Charlie Liang Yuan
Incluya los detalles relevantes en su respuesta, no solo un enlace.
jhpratt GOFUNDME RELICENSING
6

En algún momento vemos ?al final de la URL, encontré algunas soluciones que generan resultados como file.php?&foo=bar. ¡Se me ocurrió mi propia solución que funciona perfectamente como quiero!

location.origin + location.pathname + location.search + (location.search=='' ? '?' : '&') + 'lang=ar'

Nota: location.origin no funciona en IE, aquí está su solución .

Mr.Shan0
fuente
6

La siguiente función lo ayudará a agregar, actualizar y eliminar parámetros ao desde la URL.

// ejemplo1y

var myURL = '/search';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search

// ejemplo2

var myURL = '/search?category=mobile';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?category=mobile&location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?category=mobile&location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search?category=mobile

// ejemplo3

var myURL = '/search?location=texas';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search

// ejemplo4

var myURL = '/search?category=mobile&location=texas';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?category=mobile&location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?category=mobile&location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search?category=mobile

// ejemplo5

var myURL = 'https://example.com/search?location=texas#fragment';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california#fragment

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york#fragment

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search#fragment

Aquí está la función.

function updateUrl(url,key,value){
      if(value!==undefined){
        value = encodeURI(value);
      }
      var hashIndex = url.indexOf("#")|0;
      if (hashIndex === -1) hashIndex = url.length|0;
      var urls = url.substring(0, hashIndex).split('?');
      var baseUrl = urls[0];
      var parameters = '';
      var outPara = {};
      if(urls.length>1){
          parameters = urls[1];
      }
      if(parameters!==''){
        parameters = parameters.split('&');
        for(k in parameters){
          var keyVal = parameters[k];
          keyVal = keyVal.split('=');
          var ekey = keyVal[0];
          var evalue = '';
          if(keyVal.length>1){
              evalue = keyVal[1];
          }
          outPara[ekey] = evalue;
        }
      }

      if(value!==undefined){
        outPara[key] = value;
      }else{
        delete outPara[key];
      }
      parameters = [];
      for(var k in outPara){
        parameters.push(k + '=' + outPara[k]);
      }

      var finalUrl = baseUrl;

      if(parameters.length>0){
        finalUrl += '?' + parameters.join('&'); 
      }

      return finalUrl + url.substring(hashIndex); 
  }
lingeshram
fuente
5

Este fue mi propio intento, pero usaré la respuesta de annakata, ya que parece mucho más limpia:

function AddUrlParameter(sourceUrl, parameterName, parameterValue, replaceDuplicates)
{
    if ((sourceUrl == null) || (sourceUrl.length == 0)) sourceUrl = document.location.href;
    var urlParts = sourceUrl.split("?");
    var newQueryString = "";
    if (urlParts.length > 1)
    {
        var parameters = urlParts[1].split("&");
        for (var i=0; (i < parameters.length); i++)
        {
            var parameterParts = parameters[i].split("=");
            if (!(replaceDuplicates && parameterParts[0] == parameterName))
            {
                if (newQueryString == "")
                    newQueryString = "?";
                else
                    newQueryString += "&";
                newQueryString += parameterParts[0] + "=" + parameterParts[1];
            }
        }
    }
    if (newQueryString == "")
        newQueryString = "?";
    else
        newQueryString += "&";
    newQueryString += parameterName + "=" + parameterValue;

    return urlParts[0] + newQueryString;
}

Además, encontré este complemento jQuery de otra publicación en stackoverflow, y si necesita más flexibilidad, puede usarlo: http://plugins.jquery.com/project/query-object

Creo que el código sería (no lo he probado):

return $.query.parse(sourceUrl).set(parameterName, parameterValue).toString();
Lessan Vaezi
fuente
Gracias por compartir tu código, Lessan. He estado usando esto y funcionó muy bien. He subido una esencia de mi propia versión, editada para ser un poco más sucinta y pasar la validación JSHint. gist.github.com/jonathanconway/02a183920506acd9890a
Jonathan
3

Agregando a la respuesta de @ Vianney https://stackoverflow.com/a/44160941/6609678

Podemos importar el módulo URL incorporado en el nodo de la siguiente manera

const { URL } = require('url');

Ejemplo:

Terminal $ node
> const { URL } = require('url');
undefined
> let url = new URL('', 'http://localhost:1989/v3/orders');
undefined
> url.href
'http://localhost:1989/v3/orders'
> let fetchAll=true, timePeriod = 30, b2b=false;
undefined
> url.href
'http://localhost:1989/v3/orders'
>  url.searchParams.append('fetchAll', fetchAll);
undefined
>  url.searchParams.append('timePeriod', timePeriod);
undefined
>  url.searchParams.append('b2b', b2b);
undefined
> url.href
'http://localhost:1989/v3/orders?fetchAll=true&timePeriod=30&b2b=false'
> url.toString()
'http://localhost:1989/v3/orders?fetchAll=true&timePeriod=30&b2b=false'

Enlaces útiles:

https://developer.mozilla.org/en-US/docs/Web/API/URL https://developer.mozilla.org/en/docs/Web/API/URLSearchParams

Jinxer Albatross
fuente
3

Prueba esto.

// uses the URL class
function setParam(key, value) {
            let url = new URL(window.document.location);
            let params = new URLSearchParams(url.search.slice(1));

            if (params.has(key)) {
                params.set(key, value);
            }else {
                params.append(key, value);
            }
        }
Matěj Husák
fuente
url.searchParamses la lista de parámetros preinicializados para ese URLobjeto.
anfetamáquina
2

Me gusta la respuesta de Mehmet Fatih Yıldız, incluso él no respondió toda la pregunta.

En la misma línea que su respuesta, uso este código:

"No controla la existencia de parámetros, y no cambia el valor existente. Agrega su parámetro al final"

  /** add a parameter at the end of the URL. Manage '?'/'&', but not the existing parameters.
   *  does escape the value (but not the key)
   */
  function addParameterToURL(_url,_key,_value){
      var param = _key+'='+escape(_value);

      var sep = '&';
      if (_url.indexOf('?') < 0) {
        sep = '?';
      } else {
        var lastChar=_url.slice(-1);
        if (lastChar == '&') sep='';
        if (lastChar == '?') sep='';
      }
      _url += sep + param;

      return _url;
  }

y el probador:

  /*
  function addParameterToURL_TESTER_sub(_url,key,value){
    //log(_url);
    log(addParameterToURL(_url,key,value));
  }

  function addParameterToURL_TESTER(){
    log('-------------------');
    var _url ='www.google.com';
    addParameterToURL_TESTER_sub(_url,'key','value');
    addParameterToURL_TESTER_sub(_url,'key','Text Value');
    _url ='www.google.com?';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B&';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=1&B=2';
    addParameterToURL_TESTER_sub(_url,'key','value');

  }//*/
Loda
fuente
2

Iría con esta biblioteca pequeña pero completa para manejar URL en js:

https://github.com/Mikhus/jsurl

Joao Leme
fuente
Incluya los detalles relevantes en su respuesta, no solo un enlace.
jhpratt GOFUNDME RELICENSING
2

Esto es lo que uso cuando se trata de algunas adiciones o actualizaciones básicas de parámetros de URL en el lado del servidor como Node.js.

CoffeScript:

###
    @method addUrlParam Adds parameter to a given url. If the parameter already exists in the url is being replaced.
    @param {string} url
    @param {string} key Parameter's key
    @param {string} value Parameter's value
    @returns {string} new url containing the parameter
###
addUrlParam = (url, key, value) ->
    newParam = key+"="+value
    result = url.replace(new RegExp('(&|\\?)' + key + '=[^\&|#]*'), '$1' + newParam)
    if result is url
        result = if url.indexOf('?') != -1 then url.split('?')[0] + '?' + newParam + '&' + url.split('?')[1]
    else if url.indexOf('#') != -1 then url.split('#')[0] + '?' + newParam + '#' + url.split('#')[1]
    else url + '?' + newParam
    return result

JavaScript:

function addUrlParam(url, key, value) {
    var newParam = key+"="+value;
    var result = url.replace(new RegExp("(&|\\?)"+key+"=[^\&|#]*"), '$1' + newParam);
    if (result === url) { 
        result = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+newParam+"&"+url.split("?")[1] 
           : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+newParam+"#"+ url.split("#")[1] 
              : url+'?'+newParam));
    }
    return result;
}

var url = "http://www.example.com?foo=bar&ciao=3&doom=5#hashme";
result1.innerHTML = addUrlParam(url, "ciao", "1");
<p id="result1"></p>

magiccrafter
fuente
2

La solución más fácil, funciona si ya tienes una etiqueta o no, y la elimina automáticamente para que no siga agregando etiquetas iguales, diviértete

function changeURL(tag)
{
if(window.location.href.indexOf("?") > -1) {
    if(window.location.href.indexOf("&"+tag) > -1){

        var url = window.location.href.replace("&"+tag,"")+"&"+tag;
    }
    else
    {
        var url = window.location.href+"&"+tag;
    }
}else{
    if(window.location.href.indexOf("?"+tag) > -1){

        var url = window.location.href.replace("?"+tag,"")+"?"+tag;
    }
    else
    {
        var url = window.location.href+"?"+tag;
    }
}
  window.location = url;
}

LUEGO

changeURL("i=updated");
Tumba Kuza
fuente
2

La respuesta de Vianney Bajart es correcta; sin embargo, la URL solo funcionará si tiene la URL completa con puerto, host, ruta y consulta:

new URL('http://server/myapp.php?id=10&enabled=true')

Y URLSearchParams solo funcionará si pasa solo la cadena de consulta:

new URLSearchParams('?id=10&enabled=true')

Si tiene una URL incompleta o relativa y no le importa la URL base, puede dividirse por ?para obtener la cadena de consulta y unirse más tarde de esta manera:

function setUrlParams(url, key, value) {
  url = url.split('?');
  usp = new URLSearchParams(url[1]);
  usp.set(key, value);
  url[1] = usp.toString();
  return url.join('?');
}

let url = 'myapp.php?id=10';
url = setUrlParams(url, 'enabled', true);  // url = 'myapp.php?id=10&enabled=true'
url = setUrlParams(url, 'id', 11);         // url = 'myapp.php?id=11&enabled=true'

No es compatible con Internet Explorer.

iau
fuente
Si lo usa var u = new URL(window.location), usp = u.searchParams;, no tiene que usar ninguna división elegante de cadenas.
anfetamáquina
Si bien su solución funcionará para la mayoría de las cosas, destrozará la URL si tiene un signo de interrogación en un valor de parámetro:setUrlParams('https://example.com?foo=thing???&bar=baz', 'baz', 'qux') => "https://example.com?foo=thing&baz=qux???&bar=baz"
anfetamaquina el
1

Si estás jugando con URL en enlaces o en otro lugar, es posible que también tengas que tener en cuenta el hash. Aquí hay una solución bastante simple de entender. Probablemente no sea el MÁS RÁPIDO ya que usa una expresión regular ... pero en el 99.999% de los casos, ¡la diferencia realmente no importa!

function addQueryParam( url, key, val ){
    var parts = url.match(/([^?#]+)(\?[^#]*)?(\#.*)?/);
    var url = parts[1];
    var qs = parts[2] || '';
    var hash = parts[3] || '';

    if ( !qs ) {
        return url + '?' + key + '=' + encodeURIComponent( val ) + hash;
    } else {
        var qs_parts = qs.substr(1).split("&");
        var i;
        for (i=0;i<qs_parts.length;i++) {
            var qs_pair = qs_parts[i].split("=");
            if ( qs_pair[0] == key ){
                qs_parts[ i ] = key + '=' + encodeURIComponent( val );
                break;
            }
        }
        if ( i == qs_parts.length ){
            qs_parts.push( key + '=' + encodeURIComponent( val ) );
        }
        return url + '?' + qs_parts.join('&') + hash;
    }
}
theozero
fuente
No estoy seguro de por qué alguien te rechazó. Esta es una de las soluciones más confiables, aunque es mucho más código del necesario.
Adam Leggett
1

La solución más simple que se me ocurre es este método, que devolverá el URI modificado. Siento que la mayoría de ustedes está trabajando demasiado duro.

function setParam(uri, key, val) {
    return uri
        .replace(new RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}
Adam Leggett
fuente
0

Ok, aquí comparo dos funciones, una hecha por mí (regExp) y otra hecha por (annakata).

Matriz dividida:

function insertParam(key, value)
{
    key = escape(key); value = escape(value);

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

    var i=kvp.length; var x; while(i--) 
    {
        x = kvp[i].split('=');

        if (x[0]==key)
        {
                x[1] = value;
                kvp[i] = x.join('=');
                break;
        }
    }

    if(i<0) {kvp[kvp.length] = [key,value].join('=');}

    //this will reload the page, it's likely better to store this until finished
    return "&"+kvp.join('&'); 
}

Método Regexp:

function addParameter(param, value)
{
    var regexp = new RegExp("(\\?|\\&)" + param + "\\=([^\\&]*)(\\&|$)");
    if (regexp.test(document.location.search)) 
        return (document.location.search.toString().replace(regexp, function(a, b, c, d)
        {
                return (b + param + "=" + value + d);
        }));
    else 
        return document.location.search+ param + "=" + value;
}

Caso de prueba:

time1=(new Date).getTime();
for (var i=0;i<10000;i++)
{
addParameter("test","test");
}
time2=(new Date).getTime();
for (var i=0;i<10000;i++)
{
insertParam("test","test");
}

time3=(new Date).getTime();

console.log((time2-time1)+" "+(time3-time2));

Parece que incluso con la solución más simple (cuando regexp usa solo la prueba y no ingresa a la función .replace) aún es más lento que la división ... Bueno. Regexp es un poco lento pero ... uhh ...

Fotografía de Paweł Witkowski
fuente
como mencioné, esto es en realidad relativamente lento, y por supuesto, document.location.search es más claro
annakata
0

Esto es lo que hago. Usando mi función editParams (), puede agregar, eliminar o cambiar cualquier parámetro, luego usar la función incorporada replaceState () para actualizar la URL:

window.history.replaceState('object or string', 'Title', 'page.html' + editParams('enable', 'true'));


// background functions below:

// add/change/remove URL parameter
// use a value of false to remove parameter
// returns a url-style string
function editParams (key, value) {
  key = encodeURI(key);

  var params = getSearchParameters();

  if (Object.keys(params).length === 0) {
    if (value !== false)
      return '?' + key + '=' + encodeURI(value);
    else
      return '';
  }

  if (value !== false)
    params[key] = encodeURI(value);
  else
    delete params[key];

  if (Object.keys(params).length === 0)
    return '';

  return '?' + $.map(params, function (value, key) {
    return key + '=' + value;
  }).join('&');
}

// Get object/associative array of URL parameters
function getSearchParameters () {
  var prmstr = window.location.search.substr(1);
  return prmstr !== null && prmstr !== "" ? transformToAssocArray(prmstr) : {};
}

// convert parameters from url-style string to associative array
function transformToAssocArray (prmstr) {
  var params = {},
      prmarr = prmstr.split("&");

  for (var i = 0; i < prmarr.length; i++) {
    var tmparr = prmarr[i].split("=");
    params[tmparr[0]] = tmparr[1];
  }
  return params;
}
Bobb Fwed
fuente
0

Lo mejor que puedo decir es que ninguna de las respuestas anteriores aborda el caso en el que la cadena de consulta contiene parámetros que son en sí mismos una matriz y, por lo tanto, aparecerán más de una vez, por ejemplo:

http://example.com?sizes[]=a&sizes[]=b

La siguiente función es lo que escribí para actualizar document.location.search. Toma una matriz de matrices de pares clave / valor como argumento y devolverá una versión revisada de esta última con la que puede hacer lo que quiera. Lo estoy usando así:

var newParams = [
    ['test','123'],
    ['best','456'],
    ['sizes[]','XXL']
];
var newUrl = document.location.pathname + insertParams(newParams);
history.replaceState('', '', newUrl);

Si la url actual era:

http://example.com/index.php?test=replaceme&sizes[]=XL

Esto te atraparía

http://example.com/index.php?test=123&sizes[]=XL&sizes[]=XXL&best=456

Función

function insertParams(params) {
    var result;
    var ii = params.length;
    var queryString = document.location.search.substr(1);
    var kvps = queryString ? queryString.split('&') : [];
    var kvp;
    var skipParams = [];
    var i = kvps.length;
    while (i--) {
        kvp = kvps[i].split('=');
        if (kvp[0].slice(-2) != '[]') {
            var ii = params.length;
            while (ii--) {
                if (params[ii][0] == kvp[0]) {
                    kvp[1] = params[ii][1];
                    kvps[i] = kvp.join('=');
                    skipParams.push(ii);
                }
            }
        }
    }
    var ii = params.length;
    while (ii--) {
        if (skipParams.indexOf(ii) === -1) {
            kvps.push(params[ii].join('='));
        }
    }
    result = kvps.length ? '?' + kvps.join('&') : '';
    return result;
}
Billynoah
fuente
0

Pruebe
las expresiones regulares, tan lentas, por lo tanto:

var SetParamUrl = function(_k, _v) {// replace and add new parameters

    let arrParams = window.location.search !== '' ? decodeURIComponent(window.location.search.substr(1)).split('&').map(_v => _v.split('=')) : Array();
    let index = arrParams.findIndex((_v) => _v[0] === _k); 
    index = index !== -1 ? index : arrParams.length;
    _v === null ? arrParams = arrParams.filter((_v, _i) => _i != index) : arrParams[index] = [_k, _v];
    let _search = encodeURIComponent(arrParams.map(_v => _v.join('=')).join('&'));

    let newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + (arrParams.length > 0 ? '?' +  _search : ''); 

    // window.location = newurl; //reload 

    if (history.pushState) { // without reload  
        window.history.pushState({path:newurl}, null, newurl);
    }

};

var GetParamUrl = function(_k) {// get parameter by key

    let sPageURL = decodeURIComponent(window.location.search.substr(1)),
        sURLVariables = sPageURL.split('&').map(_v => _v.split('='));
    let _result = sURLVariables.find(_v => _v[0] === _k);
    return _result[1];

};

Ejemplo:

        // https://some.com/some_path
        GetParamUrl('cat');//undefined
        SetParamUrl('cat', "strData");// https://some.com/some_path?cat=strData
        GetParamUrl('cat');//strData
        SetParamUrl('sotr', "strDataSort");// https://some.com/some_path?cat=strData&sotr=strDataSort
        GetParamUrl('sotr');//strDataSort
        SetParamUrl('cat', "strDataTwo");// https://some.com/some_path?cat=strDataTwo&sotr=strDataSort
        GetParamUrl('cat');//strDataTwo
        //remove param
        SetParamUrl('cat', null);// https://some.com/some_path?sotr=strDataSort
amiron
fuente
0

Con los nuevos logros en JS, así es como se puede agregar el parámetro de consulta a la URL:

var protocol = window.location.protocol,
    host = '//' + window.location.host,
    path = window.location.pathname,
    query = window.location.search;

var newUrl = protocol + host + path + query + (query ? '&' : '?') + 'param=1';

window.history.pushState({path:newUrl}, '' , newUrl);

También vea esta posibilidad Moziila URLSearchParams.append ()

Todo está bien
fuente
0

Esto funcionará en todos los navegadores modernos.

function insertParam(key,value) {
      if (history.pushState) {
          var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' +key+'='+value;
          window.history.pushState({path:newurl},'',newurl);
      }
    }
Prasobh.Kollattu
fuente
0

Restablecer toda la cadena de consulta

var params = { params1:"val1", params2:"val2" };
let str = jQuery.param(params);

let uri = window.location.href.toString();
if (uri.indexOf("?") > 0)
   uri = uri.substring(0, uri.indexOf("?"));

console.log(uri+"?"+str);
//window.location.href = uri+"?"+str;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Bashirpour
fuente