如何更改url参数值而不影响其他参数值

时间:2018-01-24 03:53:43

标签: javascript jquery url

这里我试图根据点击的按钮将其中一个URL参数值更改为true或false。

在这里说我有一个网址

127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=false&copyfalse=copy

我希望根据我点击的按钮将值styleAttrSaved更改为true或false而不影响任何其他参数,因此一旦我更改了值,url保持不变,只更改了该值。

这是我试图做的事情。

$('.submitForm').click(function(){
    var currentUrl = window.location.href;
    var cleanUrl = currentUrl.substring(0,currentUrl.indexOf('&')

    if($(this).attr('data-des') == true){
      var savedUrl = "&styleAttrSaved=true";
    } else {
      var savedUrl = "&styleAttrSaved=false";
    } 
        var finalUrl = cleanUrl+savedUrl;
    history.pushState(null,null,finalUrl);
});


<button class="submitForm" data-des="true">Submit true</button>
<button class="submitForm" data-des="false">Submit false</button>

这里的代码我试图通过使用子字符串方法替换值。我在这里面临的问题是,如果我使用此方法,整个URL将被更改

例如,如果我有网址

127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=false&copyfalse=copy

我应用上述功能后,这个URL我回来了

127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=true

在上面的输出网址中,您可以看到styleAttrSaved的值已更改,但其他参数值copyfalse=copy在新网址的输出中不再可用。我不想删除其他参数从URL,但我应该只更改URL中一个参数的值,以便url保持相同,只有styleAttrSaved的值变为true,如此

127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=true&copyfalse=copy

我该怎么做?

6 个答案:

答案 0 :(得分:3)

您可以使用URLSearchParams轻松更改参数。 IE和Safari移动设备目前不支持它,但它们有polyfill

&#13;
&#13;
var myURL = "127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=false&copyfalse=copy";

let parsedURL = new URL(`http://${myURL}`);

parsedURL.searchParams.set("styleAttrSaved", true);

console.log(parsedURL.toString());
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这是因为你获得了&#39;&amp;&#39;的第一个索引。你必须找到&#39;&amp;&#39;

的第二个索引
function getIndex(url, subStr, indexValue) {
   return url.split(subStr, indexValue).join(subStr).length;
}
var currentUrl = window.location.href;
var preUrl = currentUrl.substring(0,getIndex(currentUrl,"&",1));
var afterurl = currentUrl.substring(getIndex(currentUrl,"&",2),currentUrl.length);
if($(this).attr('data-des') == true){
      var savedUrl = "&styleAttrSaved=true";
    } else {
      var savedUrl = "&styleAttrSaved=false";
    } 
        var finalUrl = cleanUrl+savedUrl+afterurl;
    history.pushState(null,null,finalUrl);
});

答案 2 :(得分:1)

根据调用的次数/这些URL字符串可以获得多长时间,这应该是可行的。我没有测试过,所以我不知道如何可行,但它很快。

我的基本想法是从uri string =&gt;转换对象,您可以在其中更改键的值,然后从object =&gt; uri尾部字符串返回(您显然知道URL的第一部分,或者它存储在您可以使用的某个地方)。

这个问题对我来说很有意思,所以我可能会稍微回顾一下我发现自己喜欢的方式。

请记住,你可以在你获得的URL字符串上运行String.replace,就像这样(如果你只是要改变那部分,这可能会更快地提高性能)

urlString.replace(/styleAttrSaved=(true|false)/, 'styleAttrSaved='+false

更复杂的解决方案

let url = '127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=false&copyfalse=copy';
//Base URL String
function buildObjFromUrlParams(urlString){
  let matches = urlString.match(/\?(.*)/)[1], retObj={};
  //the matches only of anything on the URL after the ? character. Maybe a better Regex but this was the one I came up with based on a single sample
  retObj = matches.split('&').reduce(function(cum, cur){
    //split the matches by the & symbol, run them through the reduce function
    let [key, val] = cur.split('=');
    //Let the key equal the first index value, and val the second, from the current loop item split by the '=' character
    cum[key]=val;
    //set the key on the cumulative object equal to the value 
    // Note you may want to run a uridecode call on the value
    return cum;
    //return the object for use in next iterator
  }, retObj); //start off with an empty Object.
  
  return retObj;
  //You could realistically replace retObj with the matches.split... call up top, but I did this for personal readability
  
}

function buildUriTailFromObj(obj){
  let keys = Object.keys(obj), retStr = '';
  //declare the object's keys + the return string
  retStr = keys.map(function(key){
    //set the return string to the map of each key value 
    return key+'='+obj[key];
    //return the string made by combining the value of the string, the equal sign, and the object value.
    //NOTE may want ot add a uriencode call on the obj[key]
  }).join('&');// join the mapped string array by the & symbol
  
  return retStr;
  
}

let urlObj = buildObjFromUrlParams(url);
urlObj.styleAttrSaved=true;


buildUriTailFromObj(urlObj);

答案 3 :(得分:1)

尝试以下常用方法:

var url= '127.0.0.1:8080/cars/model?id=2003&styleAttrSaved=false&copyfalse=copy';

function changeParam(url,paramName,paramValue){
	var qind = url.indexOf('?');
	var params = url.substring(qind).split('&');
	var query = '';
	for(var i=0;i<params.length;i++) {
		var tokens = params[i].split('=');
		var name = tokens[0];
		var value = tokens[1];
		if(name == paramName) {
			value = paramValue;
		}
		if(query == '') {
			query = name + '=' + value;
		} else {
			query = query + '&' + name + '=' + value;
		}
	}
	return url.substring(0,qind) + query;
}

console.log(changeParam(url,'styleAttrSaved','true'));

答案 4 :(得分:1)

就个人而言,我会重新考虑你的设计。您可能希望能够在需要时更改其中任何一项。使用面向对象的代码可以设置任何获取URL属性。

function GetHandler(queryString){
  var searchStr = queryString || location.search;
  searchStr = searchStr.replace('?', '');
  var searchArray = searchStr.split('&');
  this.searchObj = {};
  for(var i=0,s,l=searchArray.length; i<l; i++){
    s = searchArray[i].split('='); this.searchObj[decodeURIComponent(s[0])] = decodeURIComponent(s[1]);
  }
  this.getPropVal = function(prop){
    return this.searchObj[prop];
  }
  this.setPropVal = function(prop, val){
    this.searchObj[prop] = val;
    return this;
  }
  this.removeProp = function(prop){
    var o = {};
    for(var i in this.searchObj){
      if(i !== prop)o[i] = this.searchObj[i];
    }
    this.searchObj = o;
    return this;
  }
  this.buildSearchStr = function(){
    var a = [], so = this.searchObj;
    for(var i in so){
      a.push(encodeURIComponent(i)+'='+encodeURIComponent(so[i]));
    }
    return a.join('&');
  }
}

var getHandler = new GetHandler('?id=2003&styleAttrSaved=false&copyfalse=copy');
console.log(getHandler.searchObj);
getHandler.setPropVal('styleAttrSaved', true);
getHandler.searchObj.id = 'Anything You Want Here';
console.log(getHandler.searchObj);
console.log(getHandler.buildSearchStr());

如果您希望它基于当前页面获取URL,请删除GetHandler参数。单击“运行代码段”按钮后向下滚动到底部,以查看所需的结果。

答案 5 :(得分:1)

您更新的网址不完整的原因是您获取原始查询字符串的方式。

var cleanUrl = currentUrl.substring(0,currentUrl.indexOf('&'));

href 中的所有字符分配到&字符的第一个实例(零索引)。

依赖于特定查询参数顺序的解决方案可能有点脆弱。考虑另一种更新URL部分的方法:

function buildParameterObject(query) {
    var parameters = {};
    var querySegments = query.slice(1).split("&");      
    querySegments.forEach(function(segment) {
        var prop = segment.split("=")[0];
        var val = segment.split("=")[1] || "";
        parameters[prop] = val;
    });
    return parameters;  
}

function buildQueryString(parameters) {
    var query = "";
    if (parameters === null || typeof parameters !== "object") {
        return query;
    }
    var keys = Object.keys(parameters);
    if (keys.length === 0) {
        return query;
    }
    var querySegments = [];
    Object.keys(parameters).forEach(function(parameter) {
        var segment = parameter;
        if (parameters[parameter].length > 0) {
            segment += "=" + parameters[parameter];
        }
        querySegments.push(segment);
    });
    query = "?" + querySegments.join("&");

    return query;
}

function buildUpdatedQueryStringWithParameter(parameterName, newValue) {
    var parameters = buildParameterObject(window.location.search);
    parameters[parameterName] = newValue;
    return buildQueryString(parameters);
}

简而言之,前面的代码执行以下操作:

  • 抓取查询字符串
  • 将其转换为对象
  • 修改提供的值或将提供的参数和值添加为新的键/值对
  • 将对象转换回查询字符串
  • 返回结果字符串

因此,在您的代码中,您可以调用buildUpdatedQueryStringWithParameter,将您的参数名称和新值作为参数传递,并使用您想要的结果字符串(例如,与history.pushState()一起使用) 。