Dodanie parametru do adresu URL za pomocą JavaScript

276

W aplikacji internetowej korzystającej z wywołań AJAX muszę przesłać żądanie, ale dodać parametr na końcu adresu URL, na przykład:

Oryginalny adres URL:

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

Wynikowy adres URL:

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

Poszukuję funkcji JavaScript, która analizuje adres URL patrząc na każdy parametr, a następnie dodaje nowy parametr lub aktualizuje wartość, jeśli już istnieje.

Lessan Vaezi
źródło
Czy szukałeś parserów javascript ? Możesz stworzyć własny, dzieląc na każdy znak i, ale prawdopodobnie łatwiej jest po prostu użyć istniejącego kodu.
csl
1
Miałem kiedyś podobny scenariusz i uważam, że ten artykuł Petera Bromberga jest bardzo pomocny:
Cerebrus
2
window.history.pushState ('page2', 'Title', document.location + '/ page2.php'); wykona pracę bez ładowania strony
Rutunj sheladiya
1
To pytanie ma lepsze odpowiedzi tutaj stackoverflow.com/questions/6953944/…
rkb
niewiarygodne, że nie jest to język ojczysty w tym kiepskim języku jakim jest JS ....
bohr

Odpowiedzi:

191

Podstawowa implementacja, którą musisz dostosować, wyglądałaby mniej więcej tak:

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

Jest to około dwa razy szybsze niż rozwiązanie oparte na wyrażeniu regularnym lub wyszukiwaniu, ale zależy to całkowicie od długości kwerendy i indeksu dowolnego dopasowania


metoda powolnego wyrażenia regularnego, z którą porównywałem wyniki ze względu na ukończenia (około + 150% wolniej)

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
źródło
2
dzięki jeszcze raz. zobacz lessanvaezi.com/wp-content/uploads/2009/01/test.html, aby uzyskać podstawowe porównanie metod
Lessan Vaezi
16
Użycie escape () do zmiany parametrów URL jest nieprawidłowe. Działa z wartościami „+” w nich. Zamiast tego powinieneś użyć encodeURIComponent. Pełna dyskusja: xkr.us/articles/javascript/encode-compare
Antonin Hildebrand,
4
Wywołuję tę funkcję, a strona ładuje się ponownie w nieskończonej pętli. Proszę pomóż!
sumit
6
gdy w adresie URL nie ma już żadnych parametrów, pojawia się wartość? & param = wartość
Roy Toledo
9
Nie powinieneś encodeURIComponentraczej używać niż encodeURI? W przeciwnym razie wszelkie znaki takie jak =, &w swojej nazwie lub wartość będzie skorumpowanego URI.
Adrian Pronk
271

Możesz użyć jednego z tych:

Przykład:

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
źródło
2
Chciałbym dodać parametr zapytania bez wartości, np. Dodać XMLdo, http://foo.bar/?x=1&y=2aby wynik końcowy był http://foo.bar/?x=1&y=2&XML. czy to możliwe? Próbowałem url.searchParams.set('XML');, url.searchParams.set('XML', null);i url.searchParams.set('XML', undefined);- ale żaden nie pracował w Chrome 63 .
Abdull,
2
Dzięki! Szkoda, że ​​nie jest jeszcze obsługiwany przez iOS. developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
kanji
27
Szkoda, że ​​IE go nie obsługuje.
spedy
3
iOS obsługuje teraz URLSearchParams (od 9 dni po komentarzu @ kanji)
MJeffryes
8
Dobra wiadomość @MJeffryes! Nadal nie jest obsługiwany przez IE i Netscape.
Vianney Bajart
64

Dziękuję wszystkim za Twój wkład. Kiedyś annakata kod i zmodyfikowany także przypadek, w którym nie ma ciąg kwerendy w url w ogóle. Mam nadzieję, że to pomoże.

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
źródło
3
Byłoby lepiej, aby zmiany od escape(key)i escape(value)do encodeURIComponentfunkcji.
kolobok
5
czy to powinno faktycznie sprawdzić if (kvp.length==1 && kvp[0]="")?
Charles L.
@CharlesL. lepiej jestif (document.location.search)
Lyubimov Roman
58

To bardzo proste rozwiązanie. Nie kontroluje on istnienia parametrów i nie zmienia istniejącej wartości. Dodaje parametr do końca, dzięki czemu można uzyskać najnowszą wartość w kodzie zaplecza.

function addParameterToURL(param){
    _url = location.href;
    _url += (_url.split('?')[1] ? '&':'?') + param;
    return _url;
}
Mehmet Fatih Yıldız
źródło
6
powinieneś również wziąć pod uwagę „#” w url = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+part+"&"+url.split("?")[1] : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+part+"#"+ url.split("#")[1] : url+'?'+part));
adresie
2
@kanzure ta rzecz wygląda zła jak diabli, ale właśnie tego chciałem. Dzięki.
Chad von Nau,
dlaczego podzielić adres URL, aby sprawdzić, czy istnieje jedna postać? również nie zapomnij zakodować ... czegoś więcejfunction appendQs(url, key, value) { return url + (url.indexOf('?') >= 0 ? "&" : '?') + encodeURIComponent(key) + "=" + encodeURIComponent(value); };
drzaus
1
Napraw to. Ta funkcja nie sprawdza, czy parametr jest już podany. Przetestowałem to i dostałem https://localhost/preview/inventory.html?sortci=priceASC&sortci=priceASC&sortci=stitle.
Jay
@Jay, dlaczego potrzebuje naprawy? Sprawdź swoje założenia. Zduplikowane parametry ciągu zapytania są legalne, tak samo jak powielone pola formularza. W ten sposób zaimplementowane są listy pól wyboru. W HTML, które zostaną przekazane poprzez ciąg zapytania, jeśli metoda form = get.
Stephen
34

Oto znacznie uproszczona wersja, która powoduje kompromisy w zakresie czytelności i mniejszej liczby wierszy kodu zamiast mikrooptymalizowanej wydajności (i mówimy o różnicy kilku milisekund, realistycznie ... ze względu na naturę tego (działanie w lokalizacji bieżącego dokumentu ), najprawdopodobniej zostanie to uruchomione raz na stronie).

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

Następnie użyłbyś tego w ten sposób:

document.location.pathname + addUrlParam(document.location.search, 'foo', 'bar');
Garrett
źródło
1
+1 Podoba mi się, jak możesz określić coś innego niż document.location.search
Muhd,
1
+1 Wspaniale, zgadzam się, że czytelność jest ważniejsza niż mikrooptymalizacja w tym przypadku i cieszę się, że ktoś przyjął to podejście. @Muhd Może to był błąd w silniku JS, kiedy napisałeś ten komentarz, ale właśnie przetestowałem „1 $” w tym kontekście i działa dobrze.
JMTyler
Bardzo dziękuję za rozwiązanie, ale utknąłem również, jeśli chcę zastąpić wartość, a tam jest już parametr. Zamiast tego a & pisze 1 $
Codebryo
2
Garrett: Czy możesz naprawić swoją odpowiedź, aby poprawnie zastępowała istniejące parametry? To tylko kwestia zastąpienia [\?&]go ([\?&])w RegExp (sam bym go edytować, ale nie jestem pewien, czy polityka społeczności pozwala na naprawianie błędów w odpowiedziach).
opyh
To nie działa z adresem URL takim jak „ domain.tld ”, jego dodawanie „&” zamiast „?”
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);

I pamiętaj, że parametry należy zakodować przed dołączeniem do ciągu zapytania.

http://jsfiddle.net/48z7z4kx/

freedev
źródło
Mały wyciek pamięci - będziesz chciał usunąć element kontrolny, który został dodany do dokumentu przed zwróceniem.
konopie
@freedev, Nie, nie jestem pewien. ;) Trudno mi znaleźć wiarygodne źródło, ale dowody sugerują, że masz rację. Ponieważ utworzony element nigdy nie jest dołączony do DOM, powinien zostać wyczyszczony, gdy zmienna wyjdzie poza zakres. Interfejs API DOM nie jest specjalnie zaprojektowany, jeśli chodzi o skutki uboczne, więc jestem zbyt ostrożny.
konopie
To rozwiązanie dodaje ukośnik końcowy do adresów URL, które nie mają ścieżki i parametrów zmiany kolejności, które są niepotrzebnymi i prawdopodobnie niepożądanymi zmianami. Dołącza także zamiast zastępować istniejące parametry, które nie mają wartości (np http://abc.def/?a&b&b.).
Adam Leggett,
@AdamLeggett Dziękujemy za wskazanie błędu, który występuje, gdy parametr żądania nie ma wartości, właśnie naprawiłem swoją odpowiedź. Pozostałe dziwne zachowania, o których mówisz, jeśli masz rację, są generowane przez obiekt kotwicy HTML, który zwykle jest standardowym składnikiem przeglądarki. Sugeruję podwójne sprawdzenie, ponieważ bardzo mało prawdopodobne jest, że przeglądarka doda niepotrzebne lub niepożądane zachowania.
freedev
1
Celem funkcji addParam jest rzeczywiście dodawanie parametru wiele razy i być może powinieneś wiedzieć, że możesz przekazać ten sam parametr nawet z tą samą wartością wiele razy. stackoverflow.com/questions/24059773/…
freedev
19

Mam „klasę”, która to robi i oto:

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

Przesłoniłem metodę toString, więc nie ma potrzeby wywoływania QS :: getQueryString, możesz użyć QS :: toString lub, jak to zrobiłem w przykładach, polegać tylko na tym, że obiekt jest przymuszany do łańcucha.

miau
źródło
19
const urlParams = new URLSearchParams(window.location.search);

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

window.location.search = urlParams;

.set pierwszy agrument jest kluczem, drugi to wartość.

Zoidbergseasharp
źródło
1
Uwielbiam prostotę tego i to, że używa natywnych metod przeglądarki
Juan Solano,
2
To poprawna odpowiedź i powinna zostać poddana pod głosowanie. Ten nowy interfejs API jest ostateczny dla przetwarzania adresów URL
Anthony
8

Jeśli masz ciąg z adresem URL, który chcesz ozdobić paramem, możesz spróbować:

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

To znaczy, że ? będzie prefiksem parametru, ale jeśli już go masz ? w urlstring, niż & będzie prefiksem.

Poleciłbym to również zrobić, encodeURI( paramvariable )jeśli parametr nie został zakodowany na stałe, ale jest w środku paramvariable; lub jeśli masz zabawne postacie.

Zobacz kodowanie URL javascript dla korzystania z encodeURIfunkcji.

Sasa
źródło
7

Jest to prosty sposób na dodanie parametru zapytania:

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

I to więcej tutaj .

Zwróć uwagę na specyfikacje pomocy technicznej .

T04435
źródło
4
Wygląda na to, że nie jest to obsługiwane w żadnej wersji Internet Explorera
MAXE
Idealny dla urządzeń mobilnych. Kiedy Internet Explorer pojawi się na moim urządzeniu mobilnym, wyrzucę go. :-)
stillatmylinux
@MAXE masz rację IE / EDGE nie obsługuje wiele. Obsługiwane w
T04435
6

Sprawdź https://github.com/derek-watson/jsUri

Manipulowanie Uri i ciągiem zapytań w javascript.

Ten projekt zawiera doskonałą bibliotekę wyrażeń regularnych parseUri autorstwa Stevena Levithana. Możesz bezpiecznie analizować adresy URL wszystkich kształtów i rozmiarów, niezależnie od tego, czy są one nieprawidłowe czy ohydne.

Charlie Liang Yuan
źródło
404 - Żądany adres URL / p / jsuri / nie został znaleziony na tym serwerze. To wszystko co wiemy.
Aligma
1
Wygląda na to, że został przeniesiony. Zaktualizowałem adres URL. Powodzenia!
Charlie Liang Yuan
Podaj w odpowiedzi odpowiednie szczegóły, a nie tylko link.
jhpratt GOFUNDME RELICENSING
6

Kiedyś widzimy ?pod końcowym adresem URL, znalazłem rozwiązania, które generują wyniki jako file.php?&foo=bar. wymyśliłem własne rozwiązanie działające idealnie tak, jak chcę!

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

Uwaga: location.origin nie działa w IE, oto jego poprawka .

Mr.Shan0
źródło
6

Poniższa funkcja pomoże Ci dodawać, aktualizować i usuwać parametry do lub z adresu URL.

// przyklad1 i

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

// przykład2

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

// przykład3

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

// przykład4

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

// przykład5

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

Oto funkcja.

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
źródło
5

To była moja własna próba, ale użyję odpowiedzi annakata, ponieważ wydaje się ona znacznie czystsza:

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

Znalazłem też tę wtyczkę jQuery z innego postu na stackoverflow, a jeśli potrzebujesz większej elastyczności, możesz jej użyć: http://plugins.jquery.com/project/query-object

Myślałem, że kod będzie (nie testowałem):

return $.query.parse(sourceUrl).set(parameterName, parameterValue).toString();
Lessan Vaezi
źródło
Dziękujemy za udostępnienie kodu, Lessan. Korzystałem z tego i działa świetnie! Przesłałem listę mojej własnej wersji, zredagowaną tak, by była nieco bardziej zwięzła i przeszła walidację JSHint. gist.github.com/jonathanconway/02a183920506acd9890a
Jonathan
3

Dodawanie do odpowiedzi @ Vianney https://stackoverflow.com/a/44160941/6609678

Możemy zaimportować wbudowany moduł URL w węźle w następujący sposób

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

Przykład:

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'

Przydatne linki:

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

Jinxer Albatross
źródło
3

Spróbuj tego.

// 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
źródło
url.searchParamsjest wstępnie zainicjalizowaną listą parametrów dla tego URLobiektu.
amfetamachina
2

Podoba mi się odpowiedź Mehmeta Fatiha Yıldıza, nawet on nie odpowiedział na całe pytanie.

W tym samym wierszu co jego odpowiedź używam tego kodu:

„Nie kontroluje istnienia parametru i nie zmienia istniejącej wartości. Dodaje parametr do końca”

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

i tester:

  /*
  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
źródło
2

Poszedłbym z tym małą, ale kompletną bibliotekę do obsługi adresów URL w js:

https://github.com/Mikhus/jsurl

Joao Leme
źródło
Podaj w odpowiedzi odpowiednie szczegóły, a nie tylko link.
jhpratt GOFUNDME RELICENSING
2

To jest to, czego używam, jeśli chodzi o niektóre podstawowe dodatki lub aktualizacje adresu URL po stronie serwera, takie jak 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>

magik
źródło
2

Najłatwiejsze rozwiązanie, działa, jeśli masz już tag lub nie, i usuwa je automatycznie, aby nie dodawać równych tagów, baw się dobrze

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

NASTĘPNIE

changeURL("i=updated");
Kuza Grave
źródło
2

Odpowiedź Vianneya Bajarta jest poprawna; Jednak URL będzie działać tylko wtedy, gdy masz pełny adres URL z portem, host, ścieżki i zapytania:

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

I URLSearchParams będzie działać tylko wtedy, gdy przekażesz tylko ciąg zapytania:

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

Jeśli masz niepełny lub względny adres URL i nie zależy ci na podstawowym adresie URL, możesz po prostu podzielić przez, ?aby uzyskać ciąg zapytania i dołączyć później w następujący sposób:

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'

Nie jest kompatybilny z Internet Explorerem.

iau
źródło
Jeśli używasz var u = new URL(window.location), usp = u.searchParams;, nie musisz używać żadnego fantazyjnego podziału strun.
amfetamachina
Podczas gdy twoje rozwiązanie będzie działać na większość rzeczy, zmieni adres URL, jeśli ma znak zapytania w wartości parametru:setUrlParams('https://example.com?foo=thing???&bar=baz', 'baz', 'qux') => "https://example.com?foo=thing&baz=qux???&bar=baz"
amfetamachina
1

Jeśli masz problemy z urlami w linkach lub gdzieś indziej, być może będziesz musiał wziąć pod uwagę skrót. Oto dość proste do zrozumienia rozwiązanie. Prawdopodobnie nie NAJSZYBSZY, ponieważ używa wyrażenia regularnego ... ale w 99,999% przypadków różnica naprawdę nie ma znaczenia!

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
źródło
Nie jestem pewien, dlaczego ktoś cię ocenił. Jest to jedno z bardziej niezawodnych rozwiązań, chociaż jest o wiele więcej kodu niż to konieczne.
Adam Leggett,
1

Najprostszym rozwiązaniem, jakie mogę wymyślić, jest ta metoda, która zwróci zmodyfikowany identyfikator URI. Czuję, że większość z was pracuje zbyt ciężko.

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

Ok, tutaj porównuję Dwie funkcje, jedna wykonana przeze mnie (regExp), a druga przez (annakata).

Podzielona tablica:

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

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

Przypadek testowy:

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

Wydaje się, że nawet przy najprostszym rozwiązaniu (kiedy regexp używa tylko testu i nie wchodzi w funkcję .replace), to wciąż jest wolniejsze niż dzielenie ... Cóż. Regexp jest trochę powolny, ale ... uhh ...

Paweł Witkowski Fotografia
źródło
jak wspomniałem, jest to w rzeczywistości stosunkowo powolne - i fwiw, document.location.search jest wyraźniejsze
annakata
0

Oto co robię. Za pomocą mojej funkcji editParams () możesz dodawać, usuwać lub zmieniać dowolny parametr, a następnie użyć wbudowanej funkcji replaceState () do aktualizacji adresu 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
źródło
0

Jak najlepiej mogę powiedzieć, żadna z powyższych odpowiedzi nie dotyczy przypadku, w którym ciąg zapytania zawiera parametry, które same są tablicą, a zatem będą pojawiać się więcej niż jeden raz, np .:

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

Poniższą funkcję napisałem do zaktualizowania document.location.search . Bierze tablicę tablic pary klucz / wartość jako argument i zwraca poprawioną wersję tej drugiej, którą możesz zrobić, co chcesz. Używam tego w ten sposób:

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

Jeśli bieżący adres URL to:

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

To by cię dopadło

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

Funkcjonować

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
źródło
0

Wypróbuj
wyrażenia regularne, tak powolne, a zatem:

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

};

Przykład:

        // 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
źródło
0

Dzięki nowym osiągnięciom w JS można tutaj dodać parametr zapytania do adresu 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);

Zobacz także tę możliwość Moziila URLSearchParams.append ()

Wszystko dobrze
źródło
0

Działa to we wszystkich nowoczesnych przeglądarkach.

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
źródło
0

Resetuj cały ciąg zapytania

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
źródło