Bagaimana saya bisa menambah atau memperbarui parameter string kueri?

364

Dengan javascript bagaimana saya bisa menambahkan parameter string kueri ke url jika tidak ada atau jika ada, perbarui nilai saat ini? Saya menggunakan jquery untuk pengembangan sisi klien saya.

amatir
sumber
1
Sepertinya saya sudah menulis fungsi "parseQueryString" di JavaScript sekitar 100 kali selama karir saya. Itu tidak sulit. Poin kunci, String#splitmengambil parameter kedua untuk pemisahan maksimum. jQuery mapjuga akan sangat membantu.
jpsimons
Posting SO ini juga memiliki banyak solusi stackoverflow.com/questions/1090948/…
Dilip Rajkumar
1
Beberapa orang menganggap pertanyaan ini berarti "cara mengubah URL di bilah alamat" dan yang lain "cara mengubah variabel URL apa pun"
PandaWood
kemungkinan duplikat stackoverflow.com/questions/486896/…
Pengguna

Jawaban:

468

Saya menulis fungsi berikut yang mencapai apa yang ingin saya capai:

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;
  }
}
amatir
sumber
36
Jawaban ini tidak berfungsi ketika ada hash di URI - string kueri harus ditempatkan sebelum hash, kalau tidak, mereka tidak akan dikirim ke server. jsfiddle.net/4yXzR
Greg
20
[?|&]seharusnya[?&]
soju
8
Batasi pelingkupan variabel pemisah untuk fungsi lokal dengan menambahkan varsesaat sebelum deklarasi pemisah.
Andrea Salicetti
3
Saya pikir, Anda harus menambahkan value = encodeURIComponent(value);di baris pertama, jika tidak, jeda baris tidak lolos dengan benar.
Felix
18
Ini akan menangani hash juga: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz
189

Saya telah memperluas solusi dan menggabungkannya dengan yang lain yang saya temukan untuk mengganti / memperbarui / menghapus parameter querystring berdasarkan input pengguna dan mempertimbangkan jangkar url sebagai pertimbangan.

Tidak memasok nilai akan menghapus parameter, memasok satu akan menambah / memperbarui parameter. Jika tidak ada URL yang diberikan, itu akan diambil dari window.location

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

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

Memperbarui

Ada bug ketika menghapus parameter pertama dalam querystring, saya telah mengerjakan ulang regex dan tes untuk memasukkan perbaikan.

Pembaruan Kedua

Seperti yang disarankan oleh @ JarónBarends - Tweak memeriksa nilai untuk memeriksa terhadap tidak terdefinisi dan nol untuk memungkinkan pengaturan nilai 0

Pembaruan Ketiga

Ada bug di mana menghapus variabel querystring langsung sebelum tagar akan kehilangan simbol tagar yang telah diperbaiki

Pembaruan Keempat

Terima kasih @rooby untuk menunjukkan optimasi regex di objek RegExp pertama. Setel regex awal ke ([? &]) Karena ada masalah dengan penggunaan (\? | &) Yang ditemukan oleh @YonatanKarni

Pembaruan Kelima

Menghapus mendeklarasikan hash var di pernyataan if / else

ellemayo
sumber
5
Hanya memeriksa 'kebenaran' dari valueakan menyebabkan ini untuk menghapus variabel dari querystring ketika Anda menetapkan nilainya menjadi 0. jadi alih-alih if (value) {}Anda harus menggunakanif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends
1
Dalam RegExp ([? | &]) Harus benar-benar ([? &])
rooby
Lucu bagaimana itu dibawa dari solusi asli - juga bisa menggunakan (\? | &)
ellemayo
1
mendapatkan pengecualian "pengecualian reguler / grup tidak valid" pada pembuatan regex di chrome Versi 31.0.1650.63, dipecahkan dengan mengembalikan awal menjadi "([? &])"
Yonatan Karni
1
Bukan berarti ini penting kecuali saya menjadi OCD, tetapi variabelnya hashdinyatakan dua kali;)
wlingke
117

The URLSearchParams utilitas dapat berguna untuk ini dalam kombinasi dengan window.location.search. Sebagai contoh:

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

Sekarang footelah diatur untuk barterlepas dari apakah sudah ada atau belum.

Namun, penugasan di atas window.location.searchakan menyebabkan pemuatan halaman, jadi jika itu tidak diinginkan, gunakan API Sejarah sebagai berikut:

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

Sekarang Anda tidak perlu menulis regex atau logika Anda sendiri untuk menangani kemungkinan keberadaan string kueri.

Namun, dukungan browser buruk karena saat ini masih eksperimental dan hanya digunakan dalam versi terbaru dari Chrome, Firefox, Safari, iOS Safari, Browser Android, Android Chrome dan Opera. Gunakan dengan polyfill jika Anda memutuskan untuk menggunakannya.

Pembaruan: Dukungan browser telah meningkat sejak jawaban awal saya.

Anthony Manning-Franklin
sumber
mengisi polly, tidak baik, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference pada ie11 Anda mendapatkan kesalahan itu. itu bukan pollyfill jika tidak berfungsi sebagai fallback.
Val
6
Pembaruan 2019 : Dukungan browser sekarang baik untuk sebagian besar peramban kecuali IE dan beberapa peramban seluler kecil. Pollyfill baru dari ungap dengan mudah mencakup: github.com/ungap/url-search-params
Flion
Jawaban sempurna, namun itu tidak menangani usecase ketika hashtag ada di url. newRelativePathQueryvar newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
Tambah
43

Berdasarkan jawaban @ amatir (dan sekarang memasukkan perbaikan dari komentar @j_walker_dev), tetapi dengan mempertimbangkan komentar tentang tag hash di url saya menggunakan yang berikut:

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

Diedit untuk diperbaiki [?|&]di regex yang tentu saja harus [?&]seperti yang ditunjukkan dalam komentar

Sunting: Versi alternatif untuk mendukung penghapusan params URL juga. Saya telah menggunakan value === undefinedsebagai cara untuk menunjukkan penghapusan. Bisa menggunakan value === falseatau bahkan param input terpisah seperti yang diinginkan.

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

Lihat beraksi di https://jsfiddle.net/bp3tmuxh/1/

Adam
sumber
2
Jauh lebih bersih. FYI untuk pengguna ui-router sudut yang dapat memiliki "?" dalam hash juga. Memindahkan var separatorgaris ke kanan di atas pengembalian memperbaiki bug dengan "/ app # / cool? Fun = true". Ini akan memilih "&" sebagai pemisah meskipun belum ada params string kueri yang sebenarnya. Hanya klien.
j_walker_dev
3
Seperti yang ditunjukkan dalam komentar pada jawaban lain, [?|&]harus adil [?&](jika tidak akan cocok |).
bonger
1
Ya, "([?|&])"itu tidak baik. Harap perbaiki ini sebagai salah satu var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");atau var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(ekstensi yang bagus dengan cara lain!)
YakovL
ok, maaf, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");tidak berfungsi, yang kedua tidak
YakovL
Sepertinya versi ini tidak mendukung penghapusan parameter string kueri dengan menghilangkan nilainya. Apakah saya benar?
jkupczak
12

Saya menyadari pertanyaan ini sudah lama dan sudah dijawab sampai mati, tapi inilah yang saya lakukan. Saya mencoba menemukan kembali roda di sini karena saya menggunakan jawaban yang saat ini diterima dan kesalahan penanganan fragmen URL baru-baru ini menggigit saya dalam sebuah proyek.

Fungsinya di bawah. Ini cukup panjang, tetapi dibuat untuk menjadi sekuat mungkin. Saya ingin saran untuk memperpendek / memperbaikinya. Saya mengumpulkan test suite jsFiddle kecil untuk itu (atau fungsi serupa lainnya). Jika suatu fungsi dapat lulus semua tes di sana, saya katakan itu mungkin baik untuk pergi.

Pembaruan: Saya menemukan fungsi keren untuk menggunakan DOM untuk mem-parsing URL , jadi saya memasukkan teknik itu di sini. Itu membuat fungsi lebih pendek dan lebih dapat diandalkan. Alat peraga untuk penulis fungsi itu.

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

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

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

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

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

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

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

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

        return a.href;
    }

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

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

        qs_len--;

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

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

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

            key_found = true;
        }
    }   

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

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

    return a.href;
}
Dominic P
sumber
2
Ini terlihat sangat bagus, kotak uji solid + menggunakan DOM sebagai parser URL. Namun saya menemukan dua kasus: example.com/?param=val& => example.com/?param=val&&new=key --double & dan example.com/team => example.com/team?new=key diharapkan: team /? new = key beberapa redirect / team? new = key ke / team / dan kueri hilang.
Timar Ivo Batis
1
Terima kasih atas kasus tes yang gagal. Saya memperbarui biola. Yang pertama itu sulit. Ada ide tentang cara memperbaiki fungsi untuk itu? Yang kedua harus ditangani tanpa masalah dan sudah tercakup dalam ruang uji. Mungkin saya tidak mengerti Anda. Jangan ragu untuk melakukan tes biola untuk menunjukkan apa yang Anda lihat.
Dominic P
Saya menambahkan beberapa kasus uji yang saya temui dan solusi. Saya mencoba menggunakan DOM sebanyak mungkin. Terutama saya membutuhkan ini juga berfungsi untuk tautan relatif dalam domain yang sama. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis
1
@Braed Saya suka pendekatan karena meninggalkan beban berat ke browser. Seperti yang Anda lihat dari banyak jawaban di sini, masalah ini tidak sesederhana kelihatannya. Ada BANYAK kasus sudut yang perlu dicakup solusi. Sebagian besar dari mereka dilindungi secara gratis ketika Anda memanfaatkan DOM.
Dominic P
1
@Braed tentu saja melihat pada test suite yang saya tautkan dalam jawabannya. Banyak solusi di sini yang tidak bergantung pada DOM gagal karena mereka tidak memperhitungkan semua kasus tepi yang terdaftar. Sedangkan untuk membaca, mungkin instruktif untuk melihat modul URL untuk node.js. Ini tidak terkait langsung, tetapi memberi Anda gambaran tentang beberapa kompleksitas yang terlibat dalam string URL.
Dominic P
11

window.location.search adalah baca / tulis.

Namun - memodifikasi string kueri akan mengarahkan ulang halaman Anda dan menyebabkan penyegaran dari server.

Jika apa yang Anda coba lakukan adalah mempertahankan status sisi klien (dan berpotensi menjadikannya mampu bookmark), Anda ingin memodifikasi hash URL alih-alih string kueri, yang membuat Anda tetap berada di halaman yang sama (window.location. hash dibaca / tulis). Ini adalah bagaimana situs web seperti twitter.com melakukan ini.

Anda juga ingin tombol kembali berfungsi, Anda harus mengikat acara javascript ke acara perubahan hash, sebuah plugin yang bagus untuk itu adalah http://benalman.com/projects/jquery-hashchange-plugin/

Gal
sumber
4
Twitter tidak lagi memodifikasi hash! Hash sudah mati, selamat datang API Sejarah !
Alba Mendez
jauh dari mati. saya pikir Anda tinggal di alam mimpi di mana kompatibilitas browser lama tidak menjadi masalah. ini mungkin berlaku bagi Anda, tetapi tentu saja tidak demikian halnya dengan kita semua (atau bahkan mayoritas dari kita). mungkin sekarat lebih tepat ...
AaronHS
1
Satu tahun kemudian, sepertinya satu-satunya browser semi-baru yang tidak mendukungnya adalah IE 9
Douglas.Sesar
11

Jika tidak disetel atau ingin diperbarui dengan nilai baru yang dapat Anda gunakan:

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

Omong-omong, ini dalam Javascript sederhana.

EDIT

Anda mungkin ingin mencoba menggunakan plugin kueri-objek jquery

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

tradyblix
sumber
1
ini tidak akan mempertahankan parameter string kueri lainnya di url.
amatir
Anda benar, saya minta maaf .. sebagai pembaruan, saya menambahkan opsi lain untuk jawaban saya :)
tradyblix
Ini tidak berfungsi, karena tidak mereset nilai. "tambah atau perbarui"
Paolo Falomo
9

Inilah pendekatan saya: location.params()Fungsi (ditampilkan di bawah) dapat digunakan sebagai pengambil atau penyetel. Contoh:

URL yang diberikan adalah http://example.com/?foo=bar&baz#some-hash,

  1. location.params()akan kembali objek dengan semua parameter query: {foo: 'bar', baz: true}.
  2. location.params('foo')akan kembali 'bar'.
  3. location.params({foo: undefined, hello: 'world', test: true})akan mengubah URL menjadi http://example.com/?baz&hello=world&test#some-hash.

Berikut adalah params()fungsinya, yang secara opsional dapat ditugaskan ke window.locationobjek.

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

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

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

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

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

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

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

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

Ini adalah preferensi saya, dan itu mencakup kasus-kasus yang dapat saya pikirkan. Adakah yang bisa memikirkan cara untuk menguranginya menjadi satu penggantian?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}
Adam Leggett
sumber
Juga gagal beberapa testcases oleh Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis
5

Saya tahu ini cukup lama tetapi saya ingin memecat versi kerja saya di sini.

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>

CATATAN Ini adalah versi modifikasi dari @elreimundo

Paolo Falomo
sumber
2

Saya ambil dari sini (kompatibel dengan "gunakan ketat"; tidak benar-benar menggunakan jQuery):

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

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

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

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

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

Contoh penggunaan:

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

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

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

Berdasarkan jawaban yang diberikan @ellemayo, saya menemukan solusi berikut yang memungkinkan untuk menonaktifkan tag hash jika diinginkan:

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

Sebut saja seperti ini:

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

Hasil dalam:

http://my.example.com?foo=bar
RuubW
sumber
Stylistic quibble: typeof value !== 'undefined' && value !== nulllebih eksplisit, tetapi value != nullberarti hal yang sama dan lebih ringkas.
eppsilon
2

Ini adalah versi yang lebih singkat yang harus diperhatikan

  • kueri dengan atau tanpa parameter yang diberikan
  • kueri dengan beberapa nilai parameter
  • kueri yang berisi hash

Kode:

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

The regex deskripsi dapat ditemukan di sini .

CATATAN : Solusi ini didasarkan pada jawaban @amateur, tetapi dengan banyak peningkatan.

MaxZoom
sumber
2

Kode yang menambahkan daftar parameter ke url yang ada menggunakan ES6 dan jQuery:

class UrlBuilder {
    static appendParametersToUrl(baseUrl, listOfParams) {

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

        const newParams = jQuery.param(listOfParams);

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

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

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

Di mana listOfParams berada

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

Contoh Penggunaan:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Tes cepat:

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

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

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

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

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

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

Pendekatan yang berbeda tanpa menggunakan ekspresi reguler . Mendukung jangkar 'hash' di akhir url serta beberapa tanda tanya (?). Seharusnya sedikit lebih cepat daripada pendekatan ekspresi reguler.

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
}
cwill
sumber
1

Gunakan fungsi ini untuk menambah, menghapus, dan mengubah parameter string kueri dari URL berdasarkan jquery

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

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

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

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

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

    value = $.extend(value, param);

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

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

Tambahkan yang baru dan ubah parameter yang ada ke url

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

Hapus yang ada

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

Dengan menggunakan jQuerybisa kita lakukan seperti di bawah ini

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

Dalam variabel new_urlkita akan memiliki parameter kueri baru.

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

anjaneyulubatta505
sumber
0

Untuk memberikan contoh kode untuk memodifikasi window.location.searchseperti yang disarankan oleh Gal dan tradyblix:

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

Kode skrip Java untuk menemukan string kueri tertentu dan mengganti nilainya *

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

Ya saya punya masalah di mana querystring saya akan meluap dan menggandakan, tapi ini karena kelesuan saya sendiri. jadi saya bermain sedikit dan mengerjakan beberapa js jquery (sebenarnya sizzle) dan C # magick.

Jadi saya baru menyadari bahwa setelah server selesai dengan nilai yang diteruskan, nilai tidak masalah lagi, tidak ada penggunaan kembali, jika klien ingin melakukan hal yang sama ternyata akan selalu menjadi permintaan baru, bahkan jika itu adalah parameter yang sama dilewatkan. Dan itu semua sisi klien, sehingga beberapa caching / cookies dll bisa menjadi keren dalam hal itu.

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

Oke kritik dipersilahkan (ini adalah ramuan malam jadi silakan mencatat penyesuaian). Jika ini membantu, jempol, Happy Coding.

Tidak ada duplikat, setiap permintaan seunik Anda memodifikasinya, dan karena cara ini disusun, mudah untuk menambahkan lebih banyak permintaan secara dinamis dari dalam dom.

LokizFenrir
sumber
0

Berikut adalah metode alternatif menggunakan properti inbuilt dari elemen HTML anchor:

  • Menangani parameter multi-nilai.
  • Tidak ada risiko memodifikasi fragmen #, atau apa pun selain string kueri itu sendiri.
  • Mungkin sedikit lebih mudah dibaca? Tapi itu lebih lama.

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

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

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

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

	    a.href = url;

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

		    reassemble = [],
		    len = parts.length;

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

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

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

	    return a.href;
	};

GlennS
sumber
0

jika Anda ingin mengatur beberapa parameter sekaligus:

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

fungsi yang sama dengan @ amatir

jika jslint memberi Anda kesalahan, tambahkan ini setelah for for

if(params.hasOwnProperty(key))
Rachid O
sumber
Tidak menangani hash, atau parameter tidak menetapkan nilai ( http://abc.def/?a&b&c).
Adam Leggett
0

Ada banyak jawaban yang aneh dan rumit pada halaman ini. Nilai tertinggi, @ amatir, cukup baik, meskipun memiliki sedikit bulu yang tidak perlu di RegExp. Ini adalah solusi yang sedikit lebih optimal dengan pembersih RegExp dan replacepanggilan pembersih :

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

Sebagai bonus tambahan, jika uribukan string, Anda tidak akan mendapatkan kesalahan karena mencoba menelepon matchatau replacepada sesuatu yang mungkin tidak menerapkan metode tersebut.

Dan jika Anda ingin menangani kasus hash (dan Anda sudah melakukan pemeriksaan untuk HTML yang diformat dengan benar), Anda dapat memanfaatkan fungsi yang ada alih-alih menulis fungsi baru yang berisi logika yang sama:

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

Atau Anda dapat membuat sedikit perubahan pada jawaban @ Adam yang luar biasa:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&#]*", "i");
  if (re.test(uri)) {
    return uri.replace(re, '$1' + key + "=" + value);
  } else {
    var matchData = uri.match(/^([^#]*)(#.*)?$/);
    var separator = /\?/.test(uri) ? "&" : "?";    
    return matchData[0] + separator + key + "=" + value + (matchData[1] || '');
  }
}
elreimundo
sumber
2
Ini adalah tanda kurung yang hilang pada fungsi terakhir: var matchData = uri.match (/^([^#[*)(#.*)?$/
Jammer
separatortidak didefinisikan dalam updateQueryStringParamsNoHash. Dalam updateQueryStringParameter, semuanya rusak jika parameter yang Anda ganti tidak diberi nilai (misalnya http://abc.def/?a&b&c).
Adam Leggett
0

Ini harus melayani tujuan:

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

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