Is there better way to delete a parameter from a query string in a URL string in standard JavaScript other than by using a regular expression?
Here's what I've come up with so far whic开发者_JAVA技巧h seems to work in my tests, but I don't like to reinvent querystring parsing!
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;
}
"[&;]?" + parameter + "=[^&;]+"
Seems dangerous because it parameter ‘bar’ would match:
?a=b&foobar=c
Also, it would fail if parameter
contained any characters that are special in RegExp, such as ‘.’. And it's not a global regex, so it would only remove one instance of the parameter.
I wouldn't use a simple RegExp for this, I'd parse the parameters in and lose the ones you don't want.
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;
}
Modern browsers provide URLSearchParams
interface to work with search params. Which has delete
method that removes param by name.
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`)
}
You can change the URL with:
window.history.pushState({}, document.title, window.location.pathname);
this way, you can overwrite the URL without the search parameter, I use it to clean the URL after take the GET parameters.
I don't see major issues with a regex solution. But, don't forget to preserve the fragment identifier (text after the #
).
Here's my solution:
function RemoveParameterFromUrl(url, parameter) {
return url
.replace(new RegExp('[?&]' + parameter + '=[^&#]*(#.*)?$'), '$1')
.replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1');
}
And to bobince's point, yes - you'd need to escape .
characters in parameter names.
If it's an instance of URL
, use the delete
function of searchParams
let url = new URL(location.href);
url.searchParams.delete('page');
Copied from bobince answer, but made it support question marks in the query string, eg
http://www.google.com/search?q=test???+something&aq=f
Is it valid to have more than one question mark in a 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;
}
Here is what I'm using:
if (location.href.includes('?')) {
history.pushState({}, null, location.href.split('?')[0]);
}
Original URL: http://www.example.com/test/hello?id=123&foo=bar
Destination URL: http://www.example.com/test/hello
Now this answer seems even better! (not fully tested though)
This is a clean version remove query parameter with the URL class for today browsers:
function removeUrlParameter(url, paramKey)
{
var r = new URL(url);
r.searchParams.delete(paramKey);
return r.href;
}
URLSearchParams not supported on old browsers
https://caniuse.com/#feat=urlsearchparams
IE, Edge (below 17) and Safari (below 10.3) do not support URLSearchParams inside URL class.
Polyfills
URLSearchParams only polyfill
https://github.com/WebReflection/url-search-params
Complete Polyfill URL and URLSearchParams to match last WHATWG specifications
https://github.com/lifaon74/url-polyfill
Anyone interested in a regex solution I have put together this function to add/remove/update a querystring parameter. Not supplying a value will remove the parameter, supplying one will add/update the paramter. If no URL is supplied, it will be grabbed from window.location. This solution also takes the url's anchor into consideration.
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;
}
}
UPDATE
There was a bug when removing the first parameter in the querystring, I have reworked the regex and test to include a fix.
UPDATE 2
@schellmax update to fix situation where hashtag symbol is lost when removing a querystring variable directly before a hashtag
Here a solution that:
- uses URLSearchParams (no difficult to understand regex)
- updates the URL in the search bar without reload
- maintains all other parts of the URL (e.g. hash)
- removes superflous
?
in query string if the last parameter was removed
function removeParam(paramName) {
let searchParams = new URLSearchParams(window.location.search);
searchParams.delete(paramName);
if (history.replaceState) {
let searchString = searchParams.toString().length > 0 ? '?' + searchParams.toString() : '';
let newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + searchString + window.location.hash;
history.replaceState(null, '', newUrl);
}
}
Note: as pointed out in other answers URLSearchParams is not supported in IE, so use a polyfill.
Assuming you want to remove key=val parameter from URI:
function removeParam(uri) {
return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
}
Heres a complete function for adding and removing parameters based on this question and this github gist: 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);
};
You can add parameters like this:
updateQueryStringParam( 'myparam', 'true' );
And remove it like this:
updateQueryStringParam( 'myparam', null );
In this thread many said that the regex is probably not the best/stable solution ... so im not 100% sure if this thing has some flaws but as far as i tested it it works pretty fine.
Using 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;
}
The above version as a function
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;
}
You should be using a library to do URI manipulation as it is more complicated than it seems on the surface to do it yourself. Take a look at: http://medialize.github.io/URI.js/
From what I can see, none of the above can handle normal parameters and array parameters. Here's one that does.
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;
}
}
How to use it:
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
Of course, to update a parameter, just remove then add. Feel free to make a dummy function for it.
All of the responses on this thread have a flaw in that they do not preserve anchor/fragment parts of URLs.
So if your URL looks like:
http://dns-entry/path?parameter=value#fragment-text
and you replace 'parameter'
you will lose your fragment text.
The following is adaption of previous answers (bobince via LukePH) that addresses this problem:
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;
}
I practically wrote the following function to process the url parameters and get the final status as a string and redirect the page. Hopefully it benefits.
function addRemoveUrlQuery(addParam = {}, removeParam = [], startQueryChar = '?'){
let urlParams = new URLSearchParams(window.location.search);
//Add param
for(let i in addParam){
if(urlParams.has(i)){ urlParams.set(i, addParam[i]); }
else { urlParams.append(i, addParam[i]); }
}
//Remove param
for(let i of removeParam){
if(urlParams.has(i)){
urlParams.delete(i);
}
}
if(urlParams.toString()){
return startQueryChar + urlParams.toString();
}
return '';
}
For example, when I click a button, I want the page value to be deleted and the category value to be added.
let button = document.getElementById('changeCategory');
button.addEventListener('click', function (e) {
window.location = addRemoveUrlQuery({'category':'cars'}, ['page']);
});
I think it was very useful!
another direct & simpler answer would be
let url = new URLSearchParams(location.search)
let key = 'some_key'
return url.has(key)
? location.href.replace(new RegExp(`[?&]${key}=${url.get(key)}`), '')
: location.href
If you have a polyfill for URLSearchParams
or simply don't have to support Internet Explorer, that's what I would use like suggested in other answers here. If you don't want to depend on URLSearchParams
, that's how I would do it:
function removeParameterFromUrl(url, parameter) {
const replacer = (m, p1, p2) => (p1 === '?' && p2 === '&' ? '?' : p2 || '')
return url.replace(new RegExp(`([?&])${parameter}=[^&#]+([&#])?`), replacer)
}
It will replace a parameter preceded by ?
(p1
) and followed by &
(p2
) with ?
to make sure the list of parameters still starts with a question mark, otherwise, it will replace it with the next separator (p2
): could be &
, or #
, or undefined
which falls back to an empty string.
A modified version of solution by ssh_imov
function removeParam(uri, keyValue) {
var re = new RegExp("([&\?]"+ keyValue + "*$|" + keyValue + "&|[?&]" + keyValue + "(?=#))", "i");
return uri.replace(re, '');
}
Call like this
removeParam("http://google.com?q=123&q1=234&q2=567", "q1=234");
// returns http://google.com?q=123&q2=567
This returns the URL w/o ANY GET Parameters:
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 );
}
const params = new URLSearchParams(location.search)
params.delete('key_to_delete')
console.log(params.toString())
Glad you scrolled here.
I would suggest you to resolve this task by next possible solutions:
- You need to support only modern browsers (Edge >= 17) - use URLSearchParams.delete() API. It is native and obviously is the most convenient way of solving this task.
- If this is not an option, you may want to write a function to do this. Such a function does
- do not change URL if a parameter is not present
- remove URL parameter without a value, like
http://google.com/?myparm
- remove URL parameter with a value, like
http://google.com/?myparm=1
- remove URL parameter if is it in URL twice, like
http://google.com?qp=1&qpqp=2&qp=1
- Does not use
for
loop and not modify array during looping over it - is more functional
- is more readable than regexp solutions
- Before using make sure your URL is not encoded
Works in IE > 9 (ES5 version)
function removeParamFromUrl(url, param) { // url: string, param: string
var urlParts = url.split('?'),
preservedQueryParams = '';
if (urlParts.length === 2) {
preservedQueryParams = urlParts[1]
.split('&')
.filter(function(queryParam) {
return !(queryParam === param || queryParam.indexOf(param + '=') === 0)
})
.join('&');
}
return urlParts[0] + (preservedQueryParams && '?' + preservedQueryParams);
}
Fancy ES6 version
function removeParamFromUrlEs6(url, param) {
const [path, queryParams] = url.split('?');
let preservedQueryParams = '';
if (queryParams) {
preservedQueryParams = queryParams
.split('&')
.filter(queryParam => !(queryParam === param || queryParam.startsWith(`${param}=`)))
.join('&');
}
return `${path}${preservedQueryParams && `?${preservedQueryParams}`}`;
}
See how it works here
function removeParamInAddressBar(parameter) {
var url = document.location.href;
var urlparts = url.split('?');
if (urlparts.length >= 2) {
var urlBase = urlparts.shift();
var queryString = urlparts.join("?");
var prefix = encodeURIComponent(parameter) + '=';
var pars = queryString.split(/[&;]/g);
for (var i = pars.length; i-- > 0;) {
if (pars[i].lastIndexOf(prefix, 0) !== -1) {
pars.splice(i, 1);
}
}
if (pars.length == 0) {
url = urlBase;
} else {
url = urlBase + '?' + pars.join('&');
}
window.history.pushState('', document.title, url); // push the new url in address bar
}
return url;
}
If you're into jQuery, there is a good query string manipulation plugin:
- http://plugins.jquery.com/project/query-object
function removeQueryStringParameter(uri, key, value)
{
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '');
}
}
精彩评论