Wie kann ich einen Abfragezeichenfolgenparameter hinzufügen oder aktualisieren?


364

Wie kann ich mit Javascript der URL einen Abfragezeichenfolgenparameter hinzufügen, wenn dieser nicht vorhanden ist oder wenn er vorhanden ist, den aktuellen Wert aktualisieren? Ich verwende jquery für meine clientseitige Entwicklung.


1
Es scheint, als hätte ich die Funktion "parseQueryString" in meiner Karriere ungefähr 100 Mal in JavaScript geschrieben. Es ist nicht schwer. Wichtige Punkte, String#splitnimmt einen zweiten Parameter für maximale Teilungen. jQuery's mapwird ebenfalls hilfreich sein.
Jpsimons

Dieser SO-Beitrag hat auch viele Lösungen stackoverflow.com/questions/1090948/…
Dilip Rajkumar

1
Einige Leute verstehen unter dieser Frage "wie man die URL in der Adressleiste ändert" und andere "wie man eine URL-Variable ändert"
PandaWood

Antworten:


468

Ich habe die folgende Funktion geschrieben, die das erreicht, was ich erreichen möchte:

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;
  }
}

36
Diese Antwort funktioniert nicht, wenn der URI einen Hash enthält. Abfragezeichenfolgen müssen vor dem Hash stehen, sonst werden sie nicht an den Server gesendet. jsfiddle.net/4yXzR
Greg

20
[?|&]sollte sein[?&]
soju

8
Begrenzen Sie den Gültigkeitsbereich der Trennzeichenvariablen auf die lokale Funktion, indem Sie sie varunmittelbar vor der Trennzeichendeklaration hinzufügen .
Andrea Salicetti

3
Ich denke, Sie sollten value = encodeURIComponent(value);in der ersten Zeile hinzufügen , sonst werden Zeilenumbrüche nicht richtig maskiert.
Felix

18
Dies wird sich auch um den Hash kümmern: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz

189

Ich habe die Lösung erweitert und mit einer anderen kombiniert, bei der ich festgestellt habe, dass sie die Querystring-Parameter basierend auf den Benutzereingaben und unter Berücksichtigung des URL-Ankers ersetzt / aktualisiert / entfernt.

Wenn Sie keinen Wert angeben, wird der Parameter entfernt. Wenn Sie einen Wert angeben, wird der Parameter hinzugefügt / aktualisiert. Wenn keine URL angegeben wird, wird diese aus window.location abgerufen

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;
        }
    }
}

Aktualisieren

Beim Entfernen des ersten Parameters im Querystring ist ein Fehler aufgetreten. Ich habe den regulären Ausdruck überarbeitet und getestet, um einen Fix einzuschließen.

Zweites Update

Wie von @ JarónBarends vorgeschlagen - Überprüfen Sie die Wertprüfung, um sie gegen undefiniert und null zu prüfen, damit 0-Werte festgelegt werden können

Drittes Update

Es gab einen Fehler, bei dem das Entfernen einer Querystring-Variablen direkt vor einem Hashtag das Hashtag-Symbol verlor, das behoben wurde

Viertes Update

Vielen Dank an @rooby für den Hinweis auf eine Regex-Optimierung im ersten RegExp-Objekt. Setzen Sie den anfänglichen regulären Ausdruck auf ([? &]), Da bei der Verwendung von (\? | &) Von @YonatanKarni ein Problem aufgetreten ist

Fünftes Update

Das Deklarieren von Hash var in der if / else-Anweisung wird entfernt


5
Nur die Überprüfung der ‚Truthiness‘ von valueverursachen diese Variablen aus dem Abfragezeichenfolgeflag zu entfernen , wenn Sie den Wert auf 0 gesetzt , so statt if (value) {}Sie verwenden solltenif (typeOf value !== 'undefined' && value !== null) {}
Jaron Barends

1
In der RegExp ([? | &])
Sollte

Komisch, wie das von der ursprünglichen Lösung übernommen wurde - könnte auch (\? | &)
Ellemayo

1
Erhalten einer "ungültigen regulären Ausnahme / ungültigen Gruppe" -Ausnahme bei der Regex-Erstellung in Chrome Version 31.0.1650.63, gelöst durch Rückgabe des Anfangs als "([? &])"
Yonatan Karni

1
Nicht, dass dies wichtig wäre, außer dass ich OCD bin, aber die Variable hashwird zweimal deklariert;)
wlingke

117

Das Dienstprogramm URLSearchParams kann hierfür in Kombination mit hilfreich sein window.location.search. Zum Beispiel:

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

Jetzt foowurde festgelegt, barunabhängig davon, ob es bereits vorhanden war oder nicht.

Die obige Zuweisung zu window.location.searchverursacht jedoch ein Laden der Seite. Wenn dies nicht wünschenswert ist, verwenden Sie die Verlaufs-API wie folgt:

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);
}

Jetzt müssen Sie keinen eigenen regulären Ausdruck oder keine eigene Logik schreiben, um das mögliche Vorhandensein von Abfragezeichenfolgen zu behandeln.

Die Browserunterstützung ist jedoch schlecht, da sie derzeit experimentell ist und nur in neueren Versionen von Chrome, Firefox, Safari, iOS Safari, Android Browser, Android Chrome und Opera verwendet wird. Verwenden Sie es mit einer Polyfüllung, wenn Sie sie verwenden möchten.

Update: Die Browserunterstützung hat sich seit meiner ursprünglichen Antwort verbessert.


polly fill, ist nicht gut, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference auf ie11 bekommst du diesen fehler. Es ist keine Pollyfill, wenn es nicht als Fallback funktioniert.
Val

6
Update 2019 : Die Browserunterstützung ist jetzt für die meisten Browser außer IE und einigen kleinen mobilen Browsern gut. Neue Pollyfill von ungap deckt das leicht ab: github.com/ungap/url-search-params
Flion

Perfekte Antwort, jedoch nicht für den Fall, dass ein Hashtag in der URL vorhanden ist. Einfaches Anhängen von Hash an das Ende von newRelativePathQuerymacht den Trick:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec

43

Basierend auf der Antwort von @ amateur (und jetzt mit dem Fix aus dem Kommentar von @j_walker_dev), aber unter Berücksichtigung des Kommentars zu Hash-Tags in der URL verwende ich Folgendes:

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;
  }
}

Bearbeitet, um [?|&]in Regex zu korrigieren, was natürlich [?&]wie in den Kommentaren angegeben sein sollte

Bearbeiten: Alternative Version, um auch das Entfernen von URL-Parametern zu unterstützen. Ich habe value === undefinedals Weg verwendet, um die Entfernung anzuzeigen. Könnte value === falsewie gewünscht oder sogar einen separaten Eingabeparameter verwenden.

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;
  }
  }  
}

Sehen Sie es in Aktion unter https://jsfiddle.net/bp3tmuxh/1/


2
Viel sauberer. Zu Ihrer Information für Benutzer von eckigen UI-Routern, die "?" auch im Hash. Wenn Sie die var separatorZeile nach rechts über der Rückgabe verschieben, wird ein Fehler mit "/ app # / cool? Fun = true" behoben. Dies würde ein "&" als Trennzeichen wählen, obwohl es noch keine echten Abfragezeichenfolgenparameter gibt. Nur Kunden.
j_walker_dev

3
Wie in Kommentaren zu anderen Antworten ausgeführt, [?|&]sollte gerecht sein [?&](sonst wird übereinstimmen |).
Bonger

1
Ja, "([?|&])"ist nicht gut. Bitte beheben Sie dies entweder var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");oder var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(eine nette Erweiterung auf andere Weise!)
YakovL

ok, sorry, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");funktioniert nicht, der zweite funktioniert
YakovL

Es scheint, dass diese Version das Entfernen eines Abfragezeichenfolgenparameters durch Weglassen des Werts nicht unterstützt. Habe ich recht?
jkupczak


12

Mir ist klar, dass diese Frage alt ist und zu Tode beantwortet wurde, aber hier ist mein Stich. Ich versuche hier das Rad neu zu erfinden, weil ich die aktuell akzeptierte Antwort verwendet habe und der falsche Umgang mit URL-Fragmenten mich kürzlich in einem Projekt gebissen hat.

Die Funktion ist unten. Es ist ziemlich lang, aber es wurde so belastbar wie möglich gemacht. Ich würde gerne Vorschläge zur Verkürzung / Verbesserung machen. Ich habe eine kleine jsFiddle-Testsuite dafür (oder andere ähnliche Funktionen) zusammengestellt. Wenn eine Funktion dort jeden der Tests bestehen kann, ist es wahrscheinlich gut zu gehen.

Update: Ich bin auf eine coole Funktion für die Verwendung des DOM zum Parsen von URLs gestoßen , daher habe ich diese Technik hier integriert. Dies macht die Funktion kürzer und zuverlässiger. Requisiten an den Autor dieser Funktion.

/**
 * 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;
}

2
Das sieht wirklich gut aus, solide Testfälle + mit dem DOM als URL-Parser. Ich habe jedoch zwei Fälle gefunden: example.com/?param=val& => example.com/?param=val&&new=key --double & und example.com/team => example.com/team?new=key erwartet: team /? new = key einige Weiterleitungen / team? new = Schlüssel zu / team / und die Abfragen gehen verloren.
Timar Ivo Batis

1
Vielen Dank für den fehlgeschlagenen Testfall. Ich habe die Geige aktualisiert. Das erste ist hart. Irgendwelche Ideen, wie man die Funktion dafür repariert? Die zweite sollte problemlos behandelt werden und ist bereits in der Testsuite enthalten. Vielleicht verstehe ich dich aber nicht. Fühlen Sie sich frei, die Testgeige zu gabeln, um zu demonstrieren, was Sie sehen.
Dominic P

Ich habe einige Testfälle und Problemumgehungen hinzugefügt. Ich habe versucht, das DOM so oft wie möglich zu verwenden. In erster Linie brauchte ich dies, um auch für relative Links innerhalb derselben Domain zu funktionieren. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis

1
@braed Ich mag den Ansatz, weil er das schwere Heben dem Browser überlässt. Wie Sie aus vielen Antworten hier sehen, ist dieses Problem nicht so einfach, wie es scheint. Es gibt VIELE Eckfälle, die eine Lösung abdecken muss. Die meisten von ihnen sind kostenlos abgedeckt, wenn Sie das DOM nutzen.
Dominic P

1
@braed Schauen Sie sich einfach die Testsuite an, die ich in der Antwort verlinkt habe. Viele der hier aufgeführten Lösungen, die nicht auf dem DOM basieren, schlagen fehl, da sie nicht alle aufgeführten Randfälle berücksichtigen. Zum Lesen kann es hilfreich sein, sich das URL-Modul für node.js anzusehen. Es ist nicht direkt verwandt, aber es gibt Ihnen eine Vorstellung von der Komplexität, die mit URL-Zeichenfolgen verbunden ist.
Dominic P

11

window.location.search ist Lesen / Schreiben.

Wenn Sie jedoch die Abfragezeichenfolge ändern, wird die Seite, auf der Sie sich befinden, umgeleitet und vom Server aktualisiert.

Wenn Sie versuchen, den clientseitigen Status beizubehalten (und möglicherweise als Lesezeichen zu verwenden), möchten Sie den URL-Hash anstelle der Abfragezeichenfolge ändern, wodurch Sie auf derselben Seite (window.location) bleiben. Hash ist Lesen / Schreiben). So machen es Websites wie twitter.com.

Sie möchten auch, dass die Schaltfläche "Zurück" funktioniert. Sie müssen Javascript-Ereignisse an das Hash-Änderungsereignis binden, ein gutes Plugin dafür http://benalman.com/projects/jquery-hashchange-plugin/.


4
Twitter ändert Hash nicht mehr! Hash ist tot, begrüße die History API !
Alba Mendez

Es ist alles andere als tot. Ich denke, Sie leben in einem magischen Traumland, in dem die Kompatibilität älterer Browser keine Rolle spielt. Dies mag für Sie der Fall sein, aber für den Rest von uns (oder tatsächlich die Mehrheit von uns) ist dies sicherlich nicht der Fall. Vielleicht ist das Sterben angemessener ...
AaronHS

1
Ein Jahr später sieht es so aus, als ob der einzige neuere Browser, der dies nicht unterstützt, IE 9
Douglas.Sesar

11

Wenn es nicht festgelegt ist oder mit einem neuen Wert aktualisiert werden soll, können Sie Folgendes verwenden:

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

Dies ist übrigens in einfachem Javascript.

BEARBEITEN

Möglicherweise möchten Sie versuchen, das jquery- Abfrageobjekt- Plugin zu verwenden

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


1
Dadurch werden jedoch keine anderen Abfragezeichenfolgenparameter für die URL beibehalten.
Amateur

Sie haben Recht, ich entschuldige mich .. als Update habe ich meiner Antwort eine weitere Option hinzugefügt :)
tradyblix

Dies funktioniert nicht, da ein Wert nicht zurückgesetzt wird. "hinzufügen oder aktualisieren"
Paolo Falomo

9

Hier ist mein Ansatz: Die location.params()Funktion (siehe unten) kann als Getter oder Setter verwendet werden. Beispiele:

Angesichts der URL ist http://example.com/?foo=bar&baz#some-hash,

  1. location.params()gibt ein Objekt mit allen Abfrageparametern zurück : {foo: 'bar', baz: true}.
  2. location.params('foo')wird zurückkehren 'bar'.
  3. location.params({foo: undefined, hello: 'world', test: true})ändert die URL in http://example.com/?baz&hello=world&test#some-hash.

Hier ist die params()Funktion, die optional dem window.locationObjekt zugewiesen werden kann.

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('&');
};

6

Dies ist meine Präferenz und deckt die Fälle ab, an die ich denken kann. Kann sich jemand eine Möglichkeit vorstellen, es auf einen einzigen Ersatz zu reduzieren?

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

Auch scheitert einige Testfälle von Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis

5

Ich weiß, dass dies ziemlich alt ist, aber ich möchte meine Arbeitsversion hier abfeuern.

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>

HINWEIS Dies ist eine modifizierte Version von @elreimundo



2

Meine Einstellung von hier (kompatibel mit "use strict"; verwendet jQuery nicht wirklich):

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);
}

Anwendungsbeispiel:

// 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()));
});

2

Basierend auf der Antwort von @ellemayo habe ich die folgende Lösung gefunden, mit der das Hash-Tag auf Wunsch deaktiviert werden kann:

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;
}

Nennen Sie es so:

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

Ergebnisse in:

http://my.example.com?foo=bar

Stilistischer Streit: Ist typeof value !== 'undefined' && value !== nullexpliziter, value != nullbedeutet aber dasselbe und ist prägnanter.
Eppsilon

2

Hier ist eine kürzere Version, die sich darum kümmert

  • Abfrage mit oder ohne einen bestimmten Parameter
  • Abfrage mit mehreren Parameterwerten
  • Abfrage mit Hash

Code:

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);
}

Die Regex- Beschreibung finden Sie hier .

HINWEIS : Diese Lösung basiert auf der Antwort von @amateur, enthält jedoch viele Verbesserungen.


2

Code, der eine Liste von Parametern mit ES6 und jQuery an eine vorhandene URL anfügt:

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;
    }
}

Wo listOfParams ist

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

Anwendungsbeispiel:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Schnelle Tests:

    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

1

Ein anderer Ansatz ohne reguläre Ausdrücke . Unterstützt 'Hash'-Anker am Ende der URL sowie mehrere Fragezeichen (?). Sollte etwas schneller sein als der Ansatz mit regulären Ausdrücken.

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
}

1

Verwenden Sie diese Funktion, um Abfragezeichenfolgenparameter basierend auf jquery zur URL hinzuzufügen, zu entfernen und zu ändern

/**
@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];
    }
}

Fügen Sie neue hinzu und ändern Sie vorhandene Parameter zur URL

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

Vorhandene entfernen

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

1

Mit verwenden jQuerykönnen wir wie unten tun

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

In Variable new_url wir neue Abfrageparameter.

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


0

So geben Sie ein Codebeispiel für Änderungen an, window.location.searchwie von Gal und tradyblix vorgeschlagen:

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;

0

Java-Skriptcode, um eine bestimmte Abfragezeichenfolge zu finden und ihren Wert zu ersetzen *

('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;
                }
            })
        });

0

Ja, ich hatte ein Problem, bei dem mein Querystring überlief und sich duplizierte, aber das lag an meiner eigenen Trägheit. Also habe ich ein bisschen gespielt und ein bisschen js jquery (eigentlich brutzelnd) und C # magick aufgearbeitet.

Also habe ich gerade festgestellt, dass, nachdem der Server mit den übergebenen Werten fertig ist, die Werte keine Rolle mehr spielen, es keine Wiederverwendung mehr gibt. Wenn der Client das Gleiche offensichtlich tun wollte, wird es immer eine neue Anfrage sein, auch wenn es die ist gleiche Parameter werden übergeben. Und das ist alles clientseitig, so dass einige Caching / Cookies usw. in dieser Hinsicht cool sein könnten.

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

Okay, Kritik ist willkommen (dies war eine nächtliche Erfindung, also zögern Sie nicht, Anpassungen zu notieren). Wenn dies überhaupt geholfen hat, Daumen hoch, Happy Coding.

Keine Duplikate, jede Anforderung ist so eindeutig, wie Sie sie geändert haben, und aufgrund ihrer Struktur können Sie einfach mehr dynamische Abfragen innerhalb des Dom hinzufügen.


0

Hier ist eine alternative Methode, die die integrierten Eigenschaften des Anker-HTML-Elements verwendet:

  • Behandelt mehrwertige Parameter.
  • Kein Risiko, das # -Fragment oder etwas anderes als die Abfragezeichenfolge selbst zu ändern.
  • Vielleicht etwas leichter zu lesen? Aber es ist länger.

    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;
	};


0

Wenn Sie mehrere Parameter gleichzeitig einstellen möchten:

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;
}

gleiche Funktion wie bei @ amateur

Wenn jslint einen Fehler anzeigt, fügen Sie diesen nach der for-Schleife hinzu

if(params.hasOwnProperty(key))

Behandelt keine Hashes oder Parameter, denen kein Wert zugewiesen wurde ( http://abc.def/?a&b&c).
Adam Leggett

0

Auf dieser Seite gibt es viele umständliche und unnötig komplizierte Antworten. Das am besten bewertete, @ amateur's, ist ziemlich gut, obwohl es im RegExp ein bisschen unnötigen Flaum enthält. Hier ist eine etwas optimalere Lösung mit Cleaner RegExp und einem Cleaner replaceCall:

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
  ;
}

Als zusätzlichen Bonus erhalten Sie, wenn uries sich nicht um eine Zeichenfolge handelt, keine Fehler , wenn Sie versuchen, etwas aufzurufen matchoder replaceetwas aufzurufen , das diese Methoden möglicherweise nicht implementiert.

Wenn Sie den Fall eines Hashs behandeln möchten (und bereits eine Überprüfung auf ordnungsgemäß formatiertes HTML durchgeführt haben), können Sie die vorhandene Funktion nutzen, anstatt eine neue Funktion zu schreiben, die dieselbe Logik enthält:

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

Oder Sie können einige geringfügige Änderungen an der ansonsten hervorragenden Antwort von @ Adam vornehmen:

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] || '');
  }
}

2
Dies ist eine fehlende Klammer in der letzten Funktion: var matchData = uri.match (/^([^#‹*)(#.*)?$/
Jammer

separatorist nicht definiert in updateQueryStringParamsNoHash. In updateQueryStringParameterbricht alles zusammen, wenn dem Parameter, den Sie ersetzen, kein Wert zugewiesen wurde (z http://abc.def/?a&b&c. B. ).
Adam Leggett

0

Dies sollte dem Zweck dienen:

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("&");
}   
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.