Come posso eliminare un parametro della stringa di query in JavaScript?
-
06-07-2019 - |
Domanda
Esiste un modo migliore per eliminare un parametro da una stringa di query in una stringa URL in JavaScript standard oltre a utilizzare un'espressione regolare?
Ecco cosa ho escogitato finora che sembra funzionare nei miei test, ma non mi piace reinventare l'analisi delle querystring!
function RemoveParameterFromUrl( url, parameter ) {
if( typeof parameter == "undefined" || parameter == null || parameter == "" ) throw new Error( "parameter is required" );
url = url.replace( new RegExp( "\\b" + parameter + "=[^&;]+[&;]?", "gi" ), "" ); "$1" );
// remove any leftover crud
url = url.replace( /[&;]$/, "" );
return url;
}
Soluzione
"[&;]?" + parameter + "=[^&;]+"
Sembra pericoloso perché il parametro "bar" corrisponde:
?a=b&foobar=c
Inoltre, fallirebbe se parametro
contenesse caratteri speciali in RegExp, come ".". E non è una regex globale, quindi rimuoverà solo un'istanza del parametro.
Non userei un semplice RegExp per questo, analizzerei i parametri e perderei quelli che non vuoi.
function removeURLParameter(url, parameter) {
//prefer to use l.search if you have a location/link object
var urlparts = url.split('?');
if (urlparts.length >= 2) {
var prefix = encodeURIComponent(parameter) + '=';
var pars = urlparts[1].split(/[&;]/g);
//reverse iteration as may be destructive
for (var i = pars.length; i-- > 0;) {
//idiom for string.startsWith
if (pars[i].lastIndexOf(prefix, 0) !== -1) {
pars.splice(i, 1);
}
}
return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
}
return url;
}
Altri suggerimenti
Copiato dalla risposta bobince, ma ha reso supportati i punti interrogativi nella stringa della query, ad es.
http://www.google.com/search?q = test ??? + qualcosa di & amp; aq = f
È valido avere più di un punto interrogativo in un URL?
function removeUrlParameter(url, parameter) {
var urlParts = url.split('?');
if (urlParts.length >= 2) {
// Get first part, and remove from array
var urlBase = urlParts.shift();
// Join it back up
var queryString = urlParts.join('?');
var prefix = encodeURIComponent(parameter) + '=';
var parts = queryString.split(/[&;]/g);
// Reverse iteration as may be destructive
for (var i = parts.length; i-- > 0; ) {
// Idiom for string.startsWith
if (parts[i].lastIndexOf(prefix, 0) !== -1) {
parts.splice(i, 1);
}
}
url = urlBase + '?' + parts.join('&');
}
return url;
}
Browser moderni forniscono URLSearchParams
per lavorare con i parametri di ricerca. Che ha il metodo delete
che rimuove param per nome.
if (typeof URLSearchParams !== 'undefined') {
const params = new URLSearchParams('param1=1¶m2=2¶m3=3')
console.log(params.toString())
params.delete('param2')
console.log(params.toString())
} else {
console.log(`Your browser ${navigator.appVersion} does not support URLSearchParams`)
}
Non vedo grossi problemi con una soluzione regex. Ma non dimenticare di conservare l'identificatore del frammento (testo dopo il #
).
Ecco la mia soluzione:
function RemoveParameterFromUrl(url, parameter) {
return url
.replace(new RegExp('[?&]' + parameter + '=[^&#]*(#.*)?
E, a proposito di Bobince, sì, dovresti sfuggire ai caratteri .
nei nomi dei parametri.
), '$1')
.replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1');
}
E, a proposito di Bobince, sì, dovresti sfuggire ai caratteri .
nei nomi dei parametri.
Chiunque sia interessato a una soluzione regex ho messo insieme questa funzione per aggiungere / rimuovere / aggiornare un parametro querystring. Non fornire un valore rimuoverà il parametro, fornendo uno aggiungerà / aggiornerà il parametro. Se non viene fornito alcun URL, verrà catturato da window.location. Questa soluzione prende in considerazione anche l'ancora dell'URL.
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;
}
}
Aggiorna
Si è verificato un errore durante la rimozione del primo parametro nella stringa di query, ho rielaborato regex e testato per includere una correzione.
AGGIORNAMENTO 2
Aggiornamento di @schellmax per correggere la situazione in cui il simbolo hashtag viene perso quando si rimuove una variabile querystring direttamente prima di un hashtag
Puoi modificare l'URL con:
window.history.pushState({}, document.title, window.location.pathname);
in questo modo, puoi sovrascrivere l'URL senza il parametro di ricerca, lo uso per pulire l'URL dopo aver preso i parametri GET.
Supponendo di voler rimuovere il parametro key = val dall'URI:
function removeParam(uri) {
return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
}
Ecco cosa sto usando:
if (location.href.includes('?')) {
history.pushState({}, null, location.href.split('?')[0]);
}
URL originale: http://www.example.com/test/hello ? id = 123 & amp; foo = bar
URL di destinazione: http://www.example.com/test/hello
Ecco una funzione completa per l'aggiunta e la rimozione di parametri basati su questa domanda e questa sintesi github: https://gist.github.com/excalq/2961415
var updateQueryStringParam = function (key, value) {
var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
urlQueryString = document.location.search,
newParam = key + '=' + value,
params = '?' + newParam;
// If the "search" string exists, then build params from it
if (urlQueryString) {
updateRegex = new RegExp('([\?&])' + key + '[^&]*');
removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?');
if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty
params = urlQueryString.replace(removeRegex, "$1");
params = params.replace( /[&;]$/, "" );
} else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it
params = urlQueryString.replace(updateRegex, "$1" + newParam);
} else { // Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
}
window.history.replaceState({}, "", baseUrl + params);
};
Puoi aggiungere parametri come questo:
updateQueryStringParam( 'myparam', 'true' );
E rimuovilo in questo modo:
updateQueryStringParam( 'myparam', null );
In questo thread molti hanno detto che probabilmente il regex non è la soluzione migliore / stabile ... quindi non sono sicuro al 100% se questa cosa ha dei difetti ma per quanto ho provato funziona abbastanza bene.
La versione precedente come funzione
function removeURLParam(url, param)
{
var urlparts= url.split('?');
if (urlparts.length>=2)
{
var prefix= encodeURIComponent(param)+'=';
var pars= urlparts[1].split(/[&;]/g);
for (var i=pars.length; i-- > 0;)
if (pars[i].indexOf(prefix, 0)==0)
pars.splice(i, 1);
if (pars.length > 0)
return urlparts[0]+'?'+pars.join('&');
else
return urlparts[0];
}
else
return url;
}
Uso di jQuery:
function removeParam(key) {
var url = document.location.href;
var params = url.split('?');
if (params.length == 1) return;
url = params[0] + '?';
params = params[1];
params = params.split('&');
$.each(params, function (index, value) {
var v = value.split('=');
if (v[0] != key) url += value + '&';
});
url = url.replace(/&$/, '');
url = url.replace(/\?$/, '');
document.location.href = url;
}
Dovresti usare una libreria per manipolare l'URI in quanto è più complicato di quanto sembri in superficie farlo da solo. Dai uno sguardo a http://medialize.github.io/URI.js/
Da quello che posso vedere, nessuno dei precedenti può gestire parametri normali e parametri di array. Eccone uno che lo fa.
function removeURLParameter(param, url) {
url = decodeURI(url).split("?");
path = url.length == 1 ? "" : url[1];
path = path.replace(new RegExp("&?"+param+"\\[\\d*\\]=[\\w]+", "g"), "");
path = path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");
path = path.replace(/^&/, "");
return url[0] + (path.length
? "?" + path
: "");
}
function addURLParameter(param, val, url) {
if(typeof val === "object") {
// recursively add in array structure
if(val.length) {
return addURLParameter(
param + "[]",
val.splice(-1, 1)[0],
addURLParameter(param, val, url)
)
} else {
return url;
}
} else {
url = decodeURI(url).split("?");
path = url.length == 1 ? "" : url[1];
path += path.length
? "&"
: "";
path += decodeURI(param + "=" + val);
return url[0] + "?" + path;
}
}
Come si usa:
url = location.href;
-> http://example.com/?tags[]=single&tags[]=promo&sold=1
url = removeURLParameter("sold", url)
-> http://example.com/?tags[]=single&tags[]=promo
url = removeURLParameter("tags", url)
-> http://example.com/
url = addURLParameter("tags", ["single", "promo"], url)
-> http://example.com/?tags[]=single&tags[]=promo
url = addURLParameter("sold", 1, url)
-> http://example.com/?tags[]=single&tags[]=promo&sold=1
Naturalmente, per aggiornare un parametro, basta rimuovere quindi aggiungere. Sentiti libero di farne una funzione fittizia.
Tutte le risposte su questo thread hanno un difetto nel fatto che non mantengono parti di ancoraggio / frammento degli URL.
Quindi, se il tuo URL è simile:
http://dns-entry/path?parameter=value#fragment-text
e sostituisci 'parametro'
perderai il testo del tuo frammento.
Quanto segue è l'adattamento delle risposte precedenti (bobince via LukePH) che risolve questo problema:
function removeParameter(url, parameter)
{
var fragment = url.split('#');
var urlparts= fragment[0].split('?');
if (urlparts.length>=2)
{
var urlBase=urlparts.shift(); //get first part, and remove from array
var queryString=urlparts.join("?"); //join it back up
var prefix = encodeURIComponent(parameter)+'=';
var pars = queryString.split(/[&;]/g);
for (var i= pars.length; i-->0;) { //reverse iteration as may be destructive
if (pars[i].lastIndexOf(prefix, 0)!==-1) { //idiom for string.startsWith
pars.splice(i, 1);
}
}
url = urlBase + (pars.length > 0 ? '?' + pars.join('&') : '');
if (fragment[1]) {
url += "#" + fragment[1];
}
}
return url;
}
Una versione modificata della soluzione di ssh_imov
function removeParam(uri, keyValue) {
var re = new RegExp("([&\?]"+ keyValue + "*$|" + keyValue + "&|[?&]" + keyValue + "(?=#))", "i");
return uri.replace(re, '');
}
Chiama in questo modo
removeParam("http://google.com?q=123&q1=234&q2=567", "q1=234");
// returns http://google.com?q=123&q2=567
Questo restituisce l'URL senza QUALSIASI parametro GET:
var href = document.location.href;
var search = document.location.search;
var pos = href.indexOf( search );
if ( pos !== -1 ){
href = href.slice( 0, pos );
console.log( href );
}
Questa è una versione pulita rimuovi parametro di query con la classe URL per i browser di oggi:
function removeUrlParameter(url, paramKey)
{
var r = new URL(url);
r.searchParams.delete(paramKey);
return r.href;
}
URLSearchParams non supportato sui vecchi browser
https://caniuse.com/#feat=urlsearchparams
IE, Edge (sotto 17) e Safari (sotto 10.3) non supportano URLSearchParams all'interno della classe URL.
polyfills
Solo polyfill URLSearchParams
https://github.com/WebReflection/url-search-params
Completa URL Polyfill e URLSearchParams per abbinare le ultime specifiche WHATWG
Se sei in jQuery, c'è un buon plugin di manipolazione della stringa di query:
function removeQueryStringParameter(uri, key, value)
{
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '');
}
}