Javascript 如何添加或更新查询字符串参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5999118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I add or update a query string parameter?
提问by amateur
With javascript how can I add a query string parameter to the url if not present or if it present, update the current value? I am using jquery for my client side development.
使用 javascript 如何将查询字符串参数添加到 url 如果不存在或如果存在,则更新当前值?我正在使用 jquery 进行客户端开发。
回答by amateur
I wrote the following function which accomplishes what I want to achieve:
我编写了以下函数来完成我想要实现的目标:
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '' + key + "=" + value + '');
}
else {
return uri + separator + key + "=" + value;
}
}
回答by ellemayo
I have expanded the solution and combined it with another that I found to replace/update/remove the querystring parameters based on the users input and taking the urls anchor into consideration.
我扩展了该解决方案并将其与我发现的另一个解决方案相结合,以根据用户输入替换/更新/删除查询字符串参数并考虑 urls 锚点。
Not supplying a value will remove the parameter, supplying one will add/update the parameter. If no URL is supplied, it will be grabbed from window.location
不提供值将删除参数,提供一个将添加/更新参数。如果没有提供 URL,它将从 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, '' + key + "=" + value + '');
}
else {
hash = url.split('#');
url = hash[0].replace(re, '').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.
删除查询字符串中的第一个参数时出现错误,我重新编写了正则表达式并进行了测试以包含修复程序。
Second Update
第二次更新
As suggested by @JarónBarends - Tweak value check to check against undefined and null to allow setting 0 values
正如@JarónBarends 所建议的那样 - 调整值检查以检查 undefined 和 null 以允许设置 0 值
Third Update
第三次更新
There was a bug where removing a querystring variable directly before a hashtag would lose the hashtag symbol which has been fixed
有一个错误,即在主题标签之前直接删除查询字符串变量会丢失已修复的主题标签符号
Fourth Update
第四次更新
Thanks @rooby for pointing out a regex optimization in the first RegExp object. Set initial regex to ([?&]) due to issue with using (\?|&) found by @YonatanKarni
感谢@rooby 指出第一个 RegExp 对象中的正则表达式优化。由于使用@YonatanKarni 发现的 (\?|&) 问题,将初始正则表达式设置为 ([?&])
Fifth Update
第五次更新
Removing declaring hash var in if/else statement
删除 if/else 语句中声明的哈希变量
回答by Anthony Manning-Franklin
The URLSearchParamsutility can be useful for this in combination with window.location.search
. For example:
该URLSearchParams实用程序可以与组合是这个有用的window.location.search
。例如:
if ('URLSearchParams' in window) {
var searchParams = new URLSearchParams(window.location.search);
searchParams.set("foo", "bar");
window.location.search = searchParams.toString();
}
Now foo
has been set to bar
regardless of whether or not it already existed.
Nowfoo
已经设置为bar
不管它是否已经存在。
However, the above assignment to window.location.search
will cause a page load, so if that's not desirable use the History APIas follows:
但是,上面的赋值window.location.search
将导致页面加载,所以如果这不是可取的,请使用History API,如下所示:
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);
}
Now you don't need to write your own regex or logic to handle the possible existence of query strings.
现在您无需编写自己的正则表达式或逻辑来处理可能存在的查询字符串。
However, browser supportis poor as it's currently experimental and only in use in recent versions of Chrome, Firefox, Safari, iOS Safari, Android Browser, Android Chrome and Opera. Use with a polyfillif you do decide to use it.
然而,浏览器支持很差,因为它目前处于实验阶段,仅在最新版本的 Chrome、Firefox、Safari、iOS Safari、Android 浏览器、Android Chrome 和 Opera 中使用。如果您决定使用polyfill,请与polyfill一起使用。
Update:Browser support has improved since my original answer.
更新:自从我的原始答案以来,浏览器支持有所改善。
回答by Adam
Based on @amateur's answer (and now incorporating the fix from @j_walker_dev comment), but taking into account the comment about hash tags in the url I use the following:
基于@amateur 的回答(现在结合了@j_walker_dev 评论中的修复),但考虑到关于 url 中哈希标签的评论,我使用以下内容:
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
if (uri.match(re)) {
return uri.replace(re, '' + key + "=" + value + '');
} else {
var hash = '';
if( uri.indexOf('#') !== -1 ){
hash = uri.replace(/.*#/, '#');
uri = uri.replace(/#.*/, '');
}
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
return uri + separator + key + "=" + value + hash;
}
}
Edited to fix [?|&]
in regex which should of course be [?&]
as pointed out in the comments
编辑以修复[?|&]
正则表达式,这当然应该[?&]
在评论中指出
Edit: Alternative version to support removing URL params as well. I have used value === undefined
as the way to indicate removal. Could use value === false
or even a separate input param as wanted.
编辑:支持删除 URL 参数的替代版本。我已用作value === undefined
表示移除的方式。可以根据需要使用value === false
甚至单独的输入参数。
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
if( value === undefined ) {
if (uri.match(re)) {
return uri.replace(re, '');
} else {
return uri;
}
} else {
if (uri.match(re)) {
return uri.replace(re, '' + key + "=" + value + '');
} else {
var hash = '';
if( uri.indexOf('#') !== -1 ){
hash = uri.replace(/.*#/, '#');
uri = uri.replace(/#.*/, '');
}
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
return uri + separator + key + "=" + value + hash;
}
}
}
See it in action at https://jsfiddle.net/bp3tmuxh/1/
在https://jsfiddle.net/bp3tmuxh/1/查看它的实际效果
回答by Mikhus
Here is my library to do that: https://github.com/Mikhus/jsurl
这是我的图书馆:https: //github.com/Mikhus/jsurl
var u = new Url;
u.query.param='value'; // adds or replaces the param
alert(u)
回答by tradyblix
If it's not set or want to update with a new value you can use:
如果未设置或想要使用新值更新,您可以使用:
window.location.search = 'param=value'; // or param=new_value
This is in simple Javascript, by the way.
顺便说一下,这是在简单的 Javascript 中。
EDIT
编辑
You may want to try using the jquery query-objectplugin
您可能想尝试使用 jquery查询对象插件
window.location.search = jQuery.query.set("param", 5);
window.location.search = jQuery.query.set("param", 5);
回答by Gal
window.location.search is read/write.
window.location.search 是读/写。
However - modifying the query string will redirect the page you're on and cause a refresh from the server.
但是 - 修改查询字符串将重定向您所在的页面并导致服务器刷新。
If what you're attempting to do is maintain client side state (and potentially make it bookmark-able), you'll want to modify the URL hash instead of the query string, which keeps you on the same page (window.location.hash is read/write). This is how web sites like twitter.com do this.
如果您试图做的是维护客户端状态(并可能使其成为书签),您将需要修改 URL 哈希而不是查询字符串,这使您保持在同一页面 (window.location.哈希是读/写)。这就是 twitter.com 等网站的做法。
You'll also want the back button to work, you'll have to bind javascript events to the hash change event, a good plugin for that is http://benalman.com/projects/jquery-hashchange-plugin/
您还需要后退按钮工作,您必须将 javascript 事件绑定到哈希更改事件,一个很好的插件是http://benalman.com/projects/jquery-hashchange-plugin/
回答by Dominic P
I realize this question is old and has been answered to death, but here's my stab at it. I'm trying to reinvent the wheel here because I was using the currently accepted answer and the mishandling of URL fragments recently bit me in a project.
我意识到这个问题已经过时了并且已经得到了死亡的回答,但这是我的尝试。我试图在这里重新发明轮子,因为我使用的是当前接受的答案,而最近在一个项目中对 URL 片段的错误处理让我感到困惑。
The function is below. It's quite long, but it was made to be as resilient as possible. I would love suggestions for shortening/improving it. I put together a small jsFiddle test suitefor it (or other similar functions). If a function can pass every one of the tests there, I say it's probably good to go.
功能如下。它很长,但它尽可能地具有弹性。我喜欢缩短/改进它的建议。我为它(或其他类似的功能)组合了一个小的jsFiddle 测试套件。如果一个函数可以通过那里的所有测试,我说它可能很好。
Update:I came across a cool function for using the DOM to parse URLs, so I incorporated that technique here. It makes the function shorter and more reliable. Props to the author of that function.
更新:我遇到了一个使用 DOM 解析 URL的很酷的函数,所以我在这里合并了该技术。它使功能更短,更可靠。向该函数的作者提供道具。
/**
* 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 + '' ) + '=' + 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;
}
回答by jake
Here's my approach: The location.params()
function (shown below) can be used as a getter or setter. Examples:
这是我的方法:该location.params()
函数(如下所示)可以用作 getter 或 setter。例子:
Given the URL is http://example.com/?foo=bar&baz#some-hash
,
鉴于 URL 是http://example.com/?foo=bar&baz#some-hash
,
location.params()
will return an object with all the query parameters:{foo: 'bar', baz: true}
.location.params('foo')
will return'bar'
.location.params({foo: undefined, hello: 'world', test: true})
will change the URL tohttp://example.com/?baz&hello=world&test#some-hash
.
location.params()
会返回一个对象所有的查询参数:{foo: 'bar', baz: true}
。location.params('foo')
会回来'bar'
。location.params({foo: undefined, hello: 'world', test: true})
将 URL 更改为http://example.com/?baz&hello=world&test#some-hash
.
Here is the params()
function, which can optionally be assigned to the window.location
object.
这是params()
函数,可以选择将其分配给window.location
对象。
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('&');
};
回答by Adam Leggett
This is my preference, and it covers the cases I can think of. Can anyone think of a way to reduce it to a single replace?
这是我的偏好,它涵盖了我能想到的情况。任何人都可以想出一种方法将其减少为单个替换吗?
function setParam(uri, key, val) {
return uri
.replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
.replace(/^([^?&]+)&/, "?");
}