javascript - Bir sorgu dizesi parametresini nasıl ekleyebilir veya güncelleyebilirim?
Javascript ile, eğer yoksa URL'ye bir sorgu dizesi parametresi nasıl ekleyebilirim veya varsa mevcut değeri nasıl güncelleyebilirim? İstemci tarafı geliştirme için jquery kullanıyorum.
Cevap #1
İstediğimi başaran aşağıdaki fonksiyonu yazdım:
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;
}
}
Cevap #2
Güncelleme (2020): URLSearchParams artık tüm modern tarayıcılar tarafından desteklenmektedir.
URLSearchParams aracı, window.location.search ile birlikte bu konuda kullanışlı olabilir. Örneğin:
if ('URLSearchParams' in window) {
var searchParams = new URLSearchParams(window.location.search);
searchParams.set("foo", "bar");
window.location.search = searchParams.toString();
}
Artık foo, önceden var olup olmadığına bakılmaksızın bar olarak ayarlandı.
Ancak, yukarıdaki window.location.search ataması bir sayfa yüklenmesine neden olacaktır, bu yüzden bu istenmiyorsa History API'sini şu şekilde kullanın:
if ('URLSearchParams' in window) {
const url = new URL(window.location)
url.searchParams.set("foo", "bar")
history.pushState(null, '', url);
}
Artık sorgu dizelerinin olası varlığını ele almak için kendi regex'inizi veya mantığınızı yazmanıza gerek yok.
Cevap #3
Çözümü genişlettim ve kullanıcıların girdilerine göre sorgu dizesi parametrelerini değiştirmek/güncellemek/kaldırmak için bulduğum başka bir çözümle birleştirdim ve URL'nin anchor kısmını da dikkate aldım.
Bir değer verilmemesi parametreyi kaldırır, bir değer verilmesi parametreyi ekler/günceller. Hiçbir URL verilmezse, window.location'dan alınacaktır.
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;
}
}
}
Güncelleme
Sorgu dizgesindeki ilk parametreyi kaldırırken bir hata vardı, düzeltmeyi eklemek için regex'i ve testi yeniden düzenledim.
İkinci Güncelleme
@JarónBarends tarafından önerildiği gibi - 0 değerin ayarlanmasına izin vermek için değer kontrolünü tanımsız ve null ile karşılaştıracak şekilde ayarlayın
Üçüncü Güncelleme
Hashtag öncesinde bir sorgu dizesi değişkenini doğrudan kaldırmanın hashtag sembolünü kaybettiren bir hata vardı ve bu düzeltildi
Dördüncü Güncelleme
İlk RegExp nesnesindeki bir regex optimizasyonunu işaret ettiği için @rooby'ya teşekkürler. @YonatanKarni tarafından bulunan (\?|&) kullanımındaki sorun nedeniyle başlangıç regex'ini ([?&]) olarak ayarladık.
Beşinci Güncelleme
if/else ifadesinde hash değişkenini tanımlamayı kaldırma
Cevap #4
Bunu çok basit bir şekilde yapmak için tarayıcının yerleşik URL API'sini kullanabilirsiniz; burada key ve value sırayla parametre adınız ve parametre değerinizdir.
const url = new URL(location.href);
url.searchParams.set(key, value);
Bu, URL hakkındaki her şeyi koruyacak ve yalnızca bir sorgu parametresini değiştirecek veya ekleyecektir.
Daha sonra url nesnesi ile istediğinizi yapabilirsiniz. Örnekler:
// Log the URL string.
console.log(url.href);
// Go to the URL.
location.assign(url);
// Go to the URL, but overwrite this history entry.
location.replace(url);
// Same as `location.assign` without reloading.
history.pushState(null, '', url);
// Same as `location.replace` without reloading.
history.replaceState(null, '', url);
Cevap #5
@amateur'un cevabına dayanarak (ve şimdi @j_walker_dev yorumundaki düzeltmeyi de ekleyerek), ancak url'deki hash etiketleri hakkındaki yorumu dikkate alarak şu şekilde kullanıyorum:
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;
}
}
Yorumlarda belirtildiği gibi elbette [?&] olması gereken regex'teki [?|&] düzeltmek için düzenlendi
Düzenleme: URL parametrelerini kaldırmayı destekleyen alternatif sürüm. Kaldırmayı belirtmek için value === undefined kullandım. İstenirse value === false veya ayrı bir giriş parametresi de kullanılabilir.
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
if( value === undefined ) {
if (uri.match(re)) {
return uri.replace(re, '$1$2').replace(/[?&]$/, '').replaceAll(/([?&])&+/g, '$1').replace(/[?&]#/, '#');
} 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;
}
}
}
https://jsfiddle.net/cdt16wex/ adresinde kullanımını görün
Cevap #6
Modern JavaScript, Node.js ve tarayıcı desteği sayesinde, üçüncü taraf kütüphane girdabından (jQuery, query-string vb.) çıkabilir ve kendimizi DRY yapabiliriz.
İşte verilen URL'nin sorgu parametrelerini ekleyen veya güncelleyen bir fonksiyon için javascript(node.js) ve typescript sürümü:
Javascript
const getUriWithParam = (baseUrl, params) => {
const Url = new URL(baseUrl);
const urlParams = new URLSearchParams(Url.search);
for (const key in params) {
if (params[key] !== undefined) {
urlParams.set(key, params[key]);
}
}
Url.search = urlParams.toString();
return Url.toString();
};
console.info('expected: https://example.com/?foo=bar');
console.log(getUriWithParam("https://example.com", {foo: "bar"}));
console.info('expected: https://example.com/slug?foo=bar#hash');
console.log(getUriWithParam("https://example.com/slug#hash", {foo: "bar"}));
console.info('expected: https://example.com/?bar=baz&foo=bar');
console.log(getUriWithParam("https://example.com?bar=baz", {foo: "bar"}));
console.info('expected: https://example.com/?foo=baz&bar=baz');
console.log(getUriWithParam("https://example.com?foo=bar&bar=baz", {foo: "baz"}));Typescript
const getUriWithParam = (
baseUrl: string,
params: Record<string, any>
): string => {
const Url = new URL(baseUrl);
const urlParams: URLSearchParams = new URLSearchParams(Url.search);
for (const key in params) {
if (params[key] !== undefined) {
urlParams.set(key, params[key]);
}
}
Url.search = urlParams.toString();
return Url.toString();
};
React Native için
URL React Native'de uygulanmamıştır. Bu yüzden önceden react-native-url-polyfill kurmanız gerekmektedir.
Nesne parametreleri için
Bu cevapta ikinci çözüme bakın
Cevap #7
Bunu yapmak için kütüphanem burada: https://github.com/Mikhus/jsurl
var u = new Url;
u.query.param='value'; // adds or replaces the param
alert(u)
Cevap #8
Eğer ayarlanmadıysa veya yeni bir değerle güncellemek istiyorsanız şunu kullanabilirsiniz:
window.location.search = 'param=value'; // or param=new_value
Bu arada bu basit Javascript ile yapılmıştır.
DÜZENLE
jquery query-object eklentisini kullanmayı deneyebilirsiniz
window.location.search=jQuery.query.set("param", 5);
Cevap #9
Bu sorunun eski olduğunu ve defalarca yanıtlandığını farkındayım, ama işte benim denemem. Burada tekerleği yeniden icat etmeye çalışıyorum çünkü şu anda kabul edilen cevabı kullanıyordum ve URL parçalarının yanlış yönetilmesi yakın zamanda bir projede bana sorun çıkardı.
Fonksiyon aşağıdadır. Oldukça uzun, ama mümkün olduğunca dayanıklı olacak şekilde yapıldı. Kısaltmak/geliştirmek için önerilere bayılırım. Bunun için (veya benzeri diğer fonksiyonlar için) küçük bir jsFiddle test seti hazırladım. Bir fonksiyon oradaki her testi geçebiliyorsa, muhtemelen kullanılmaya hazır olduğunu söyleyebilirim.
Güncelleme: URL'leri çözümlemek için DOM'u kullanmaya yarayan harika bir fonksiyonla karşılaştım, bu yüzden bu tekniği burada kullandım. Fonksiyonu daha kısa ve daha güvenilir hale getiriyor. O fonksiyonun yazarı takdir edilmeli.
/**
* 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;
}
Cevap #10
window.location.search okunur/yazılır.
Ancak - sorgu dizgisini değiştirmek, bulunduğunuz sayfayı yönlendirir ve sunucudan yenilenmesine neden olur.
Eğer yapmaya çalıştığınız şey istemci tarafı durumu korumaksa (ve potansiyel olarak yer imlerine eklenebilir hale getirmekse), sorgu dizesi yerine URL hash'ini değiştirmeniz gerekir, bu da sizi aynı sayfada tutar (window.location.hash okunabilir/yazılabilir). Twitter.com gibi web siteleri bunu böyle yapar.
Geri düğmesinin de çalışmasını isteyeceksiniz, bunun için javascript olaylarını hash değişikliği olayına bağlamanız gerekecek, bunun için iyi bir eklenti http://benalman.com/projects/jquery-hashchange-plugin/
