如何添加或更新查询字符串参数?

用javascript我怎么能添加一个查询字符串参数的url,如果不存在或如果它存在,更新当前值?我使用jquery为我的客户端开发。

518193 次浏览

如果它没有设置或想要更新一个新值,您可以使用:

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

这是用简单Javascript写的。

编辑

你可能想尝试使用jquery 查询对象插件

< p > window.location。搜索= jQuery.query。设置(“参数”,5);< / p >

Window.location.search是读/写的。

然而,修改查询字符串将重定向您所在的页面,并导致从服务器刷新。

如果您试图做的是维护客户端状态(并可能使其可书签),您将希望修改URL散列而不是查询字符串,这将使您保持在同一页面(window.location。哈希是读/写)。像twitter.com这样的网站就是这样做的。

你还想让后退按钮工作,你必须将javascript事件绑定到哈希更改事件,一个很好的插件是http://benalman.com/projects/jquery-hashchange-plugin/

我写了下面的函数来实现我想要实现的:

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

我已经扩展了解决方案,并将其与另一个我发现的替换/更新/删除基于用户输入的查询字符串参数,并将url锚纳入考虑。

不提供值将删除参数,提供值将添加/更新参数。如果没有提供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, '$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;
}
}
}

更新

在删除查询字符串中的第一个参数时,有一个错误,我重新工作了正则表达式和测试,以包括修复。

第二次更新

根据@JarónBarends的建议-调整值检查检查undefined和null,以允许设置0值

第三次更新

有一个错误,在一个标签之前直接删除一个查询字符串变量将失去标签符号,这已被修复

第四次更新

感谢@rooby在第一个RegExp对象中指出正则表达式优化。 由于使用@YonatanKarni发现的(\?|&)

,将初始正则表达式设置为([?&])

第五次更新

在if/else语句中删除声明哈希变量

My take 从这里(兼容“use strict”;并不真正使用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);
}

使用示例:

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

基于@amateur的回答(现在结合了来自@j_walker_dev评论的修复),但考虑到url中关于散列标签的评论,我使用以下方法:

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

编辑以修复正则表达式中的[?|&],当然应该是评论中指出的[?&]

编辑:支持删除 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, '$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/中可以看到它的实际操作

下面是我的库:https://github.com/Mikhus/jsurl

var u = new Url;
u.query.param='value'; // adds or replaces the param
alert(u)

给出Gal和tradyblix建议的修改window.location.search的代码示例:

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;

查找特定查询字符串并替换其值*的Java脚本代码

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

是的,我有一个问题,我的查询字符串会溢出和复制,但这是由于我自己的懒惰。所以我玩了一点,并研究了一些js jquery(实际上是sizzle)和c#魔法。

所以我才意识到,在服务器已经完成了传递的值,这些值不再重要,没有重用,如果客户端想做同样的事情,显然它将总是一个新的请求,即使它是相同的参数被传递。这些都是客户端,所以一些缓存/cookie等在这方面可能很酷。

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

好吧,欢迎批评(这是一个夜间调制,所以请随时注意调整)。如果这有帮助的话,竖起大拇指,快乐编码。 < / >强

没有重复,每个请求都是唯一的,因为你修改了它,并且由于它的结构,很容易从dom内动态添加更多的查询。

我意识到这个问题已经很老了,而且已经被回答得死去活来了,但我想尝试一下。我试图在这里重新发明轮子,因为我正在使用目前接受的答案和URL片段的错误处理,最近在一个项目中咬我一口。

函数如下。它很长,但它被设计得尽可能有弹性。我想听听缩短/改进它的建议。我为它(或其他类似的函数)组合了一个小jsFiddle测试套件。如果一个函数可以通过每一个测试,我说它可能就可以运行了。

更新:我遇到了一个很酷的使用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 + '$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;
}

下面是我的方法:location.params()函数(如下所示)可以用作getter或setter。例子:

假设URL是http://example.com/?foo=bar&baz#some-hash

  1. location.params()将返回一个包含所有查询参数的对象:
  2. location.params('foo')将返回'bar'
  3. location.params({foo: undefined, hello: 'world', test: true})将URL更改为http://example.com/?baz&hello=world&test#some-hash

下面是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('&');
};

根据@ellemayo给出的答案,我提出了以下解决方案,如果需要,可以禁用散列标签:

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

这样叫它:

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

结果:

http://my.example.com?foo=bar

下面是使用锚HTML元素的内置属性的另一种方法:

  • 处理多值参数。
  • 没有修改#片段或查询字符串本身以外的任何内容的风险。
  • 可能会更容易读?但是它更长。

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

如果你想一次设置多个参数:

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

与@amateur的函数相同

如果jslint给出了一个错误,在for循环之后添加这个

if(params.hasOwnProperty(key))

在这个页面上有很多尴尬和不必要的复杂答案。评分最高的@amateur's相当不错,尽管它在RegExp中有一些不必要的错误。下面是一个稍微更优的解决方案,使用更干净的RegExp和更干净的replace调用:

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

作为一个额外的好处,如果uri不是一个字符串,你将不会在试图调用matchreplace的东西上得到错误,这些方法可能没有实现。

如果你想处理散列的情况(并且你已经检查了正确格式化的HTML),你可以利用现有的函数,而不是写一个包含相同逻辑的新函数:

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

或者你可以对@Adam的精彩回答做一些小小的修改:

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

我知道这是相当旧的,但我想在这里发射我的工作版本

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

请注意这是@elreimundo的修改版本

这是一个简短的版本

  • 使用或不使用给定参数查询
  • 使用多个参数值查询
  • 包含散列的查询

代码:

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

正则表达式描述可以在在这里中找到。

请注意:这个解决方案是基于@amateur的答案,但是有很多改进。

这样做的目的是:

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("&");
}

更新(2020): URLSearchParams现在是所有现代浏览器的支持

URLSearchParams实用程序可以与window.location.search结合使用。例如:

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

现在foo已经被设置为bar,不管它是否已经存在。

然而,上面赋值给window.location.search会导致页面加载,所以如果不希望这样做,可以使用历史的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);
}

现在您不需要编写自己的正则表达式或逻辑来处理可能存在的查询字符串。

然而,浏览器支持是很差的,因为它目前是实验性的,只在最新版本的Chrome, Firefox, Safari, iOS Safari, Android浏览器,Android Chrome和Opera中使用。使用一个polyfill如果你决定使用它

一个不同的方法不使用正则表达式。支持url末尾的“散列”锚以及多个问号字符(?)。应该比正则表达式方法略快。

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
}

使用此函数可以添加、删除和修改URL中的查询字符串参数

/**
@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];
}
}

添加新的和修改现有参数的url

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

删除现有的

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

通过使用jQuery,我们可以像下面这样做

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

在变量new_url中,我们将有新的查询参数。

参考:http://api.jquery.com/jquery.param/

使用ES6和jQuery将参数列表追加到现有url的代码:

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

listOfParams是什么样的

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

用法示例:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

快速测试:

    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

使用URLSearchParams非常简单,所有现代浏览器都支持(caniuse)。

let p = new URLSearchParams();
p.set("foo", "bar");
p.set("name", "Jack & Jill?");
console.log("http://example.com/?" + p.toString());

如果你想修改现有的URL,像这样构造对象:new URLSearchParams(window.location.search)并将字符串赋值给window.location.search

下面是我对此略有不同的方法,作为练习写的

function addOrChangeParameters( url, params )
{
let splitParams = {};
let splitPath = (/(.*)[?](.*)/).exec(url);
if ( splitPath && splitPath[2] )
splitPath[2].split("&").forEach( k => { let d = k.split("="); splitParams[d[0]] = d[1]; } );
let newParams = Object.assign( splitParams, params );
let finalParams = Object.keys(newParams).map( (a) => a+"="+newParams[a] ).join("&");
return splitPath ? (splitPath[1] + "?" + finalParams) : (url + "?" + finalParams);
}

用法:

const url = "http://testing.com/path?empty&value1=test&id=3";


addOrChangeParameters( url, {value1:1, empty:"empty", new:0} )


"http://testing.com/path?empty=empty&value1=1&id=3&new=0"

感谢现代javascript, node.js和浏览器的支持,我们可以摆脱第三方库的漩涡(jquery, query-string等)和DRY自己。

下面是javascript(node.js)和typescript版本的函数,用于添加或更新给定url的查询参数:

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

打印稿


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

URL在React Native中没有实现。所以你必须预先安装react-native-url-polyfill

对于对象参数

参见第二个解决方案在这个答案中

这个答案只是ellemayo的答案的一个小调整。它将自动更新URL,而不只是返回更新后的字符串。

function _updateQueryString(key, value, url) {
if (!url) url = window.location.href;


let updated = ''
var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
hash;


if (re.test(url)) {
if (typeof value !== 'undefined' && value !== null) {
updated = 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];
}
updated = 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];
}
updated = url;
}
else {
updated = url;
}
}


window.history.replaceState({ path: updated }, '', updated);
}

你可以使用浏览器的原生URL API以一种相当简单的方式来做到这一点,其中keyvalue分别是你的参数名和参数值。

const url = new URL(location.href);
url.searchParams.set(key, value);


history.pushState(null, '', url);

这将保留有关URL的所有内容,只更改或添加一个查询参数。如果你不想让它创建一个新的浏览器历史记录条目,你也可以使用replaceState来代替pushState

我想要的是:

  • 使用浏览器的本机URL API
  • 可以添加、更新、获取或删除吗
  • 期望在散列之后的查询字符串,例如对于单页应用程序

function queryParam(options = {}) {


var defaults = {
method: 'set',
url: window.location.href,
key: undefined,
value: undefined,
}


for (var prop in defaults) {
options[prop] = typeof options[prop] !== 'undefined' ? options[prop] : defaults[prop]
}


const existing = (options.url.lastIndexOf('?') > options.url.lastIndexOf('#')) ? options.url.substr(options.url.lastIndexOf('?') + 1) : ''


const query = new URLSearchParams(existing)


if (options.method === 'set') {
query.set(options.key, options.value)


return `${options.url.replace(`?${existing}`, '')}?${query.toString()}`
} else if (options.method === 'get') {
const val = query.get(options.key)
let result = val === null ? val : val.toString()


return result
} else if (options.method === 'delete') {
query.delete(options.key)


let result = `${options.url.replace(`?${existing}`, '')}?${query.toString()}`
const lastChar = result.charAt(result.length - 1)


if (lastChar === '?') {
result = `${options.url.replace(`?${existing}`, '')}`
}


return result
}
}


// Usage:
let url = 'https://example.com/sandbox/#page/'


url = queryParam({
url,
method: 'set',
key: 'my-first-param',
value: 'me'
})
console.log(url)


url = queryParam({
url,
method: 'set',
key: 'my-second-param',
value: 'you'
})
console.log(url)


url = queryParam({
url,
method: 'set',
key: 'my-second-param',
value: 'whomever'
})
console.log(url)


url = queryParam({
url,
method: 'delete',
key: 'my-first-param'
})
console.log(url)


const mySecondParam = queryParam({
url,
method: 'get',
key: 'my-second-param',
})
console.log(mySecondParam)


url = queryParam({
url,
method: 'delete',
key: 'my-second-param'
})
console.log(url)