我有这个URL:

site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc

我需要的是能够改变'行' url参数值我指定的东西,让我们说10。如果“行”不存在,我需要将它添加到url的末尾,并添加我已经指定的值(10)。


当前回答

我是这么做的。使用我的editParams()函数,你可以添加,删除或更改任何参数,然后使用内置的replaceState()函数更新URL:

window.history.replaceState('object or string', 'Title', 'page.html' + editParams('sorting', ModifiedTimeAsc));


// background functions below:

// add/change/remove URL parameter
// use a value of false to remove parameter
// returns a url-style string
function editParams (key, value) {
  key = encodeURI(key);

  var params = getSearchParameters();

  if (Object.keys(params).length === 0) {
    if (value !== false)
      return '?' + key + '=' + encodeURI(value);
    else
      return '';
  }

  if (value !== false)
    params[key] = encodeURI(value);
  else
    delete params[key];

  if (Object.keys(params).length === 0)
    return '';

  return '?' + $.map(params, function (value, key) {
    return key + '=' + value;
  }).join('&');
}

// Get object/associative array of URL parameters
function getSearchParameters () {
  var prmstr = window.location.search.substr(1);
  return prmstr !== null && prmstr !== "" ? transformToAssocArray(prmstr) : {};
}

// convert parameters from url-style string to associative array
function transformToAssocArray (prmstr) {
  var params = {},
      prmarr = prmstr.split("&");

  for (var i = 0; i < prmarr.length; i++) {
    var tmparr = prmarr[i].split("=");
    params[tmparr[0]] = tmparr[1];
  }
  return params;
}

其他回答

我也在找同样的东西,发现:https://github.com/medialize/URI.js,这是相当不错:)

- - -更新

我找到了一个更好的包:https://www.npmjs.org/package/qs,它还处理get参数中的数组。

想想这个例子:

const myUrl = new URL("http://www.example.com?columns=5&rows=20");
myUrl.searchParams.set('rows', 10);
console.log(myUrl.href); // http://www.example.com?columns=5&rows=10
myUrl.searchParams.set('foo', 'bar'); // add new param
console.log(myUrl.href); // http://www.example.com?columns=5&rows=10&foo=bar

它会做和你要求的完全一样的事情。请注意URL必须有正确的格式。在你的例子中,你必须指定协议(http或https)

下面是一个使用query-string库的简单解决方案。

const qs = require('query-string')
function addQuery(key, value) {
  const q = qs.parse(location.search)
  const url = qs.stringifyUrl(
    {
      url: location.pathname,
      query: {
      ...q,
      [key]: value,
      },
    },
    { skipEmptyString: true }
  );
  window.location.href = url
  // if you are using Turbolinks
  // add this: Turbolinks.visit(url)
}
// Usage
addQuery('page', 2)

如果你使用react而不使用react-router

export function useAddQuery() {
  const location = window.location;
  const addQuery = useCallback(
    (key, value) => {
      const q = qs.parse(location.search);
      const url = qs.stringifyUrl(
        {
          url: location.pathname,
          query: {
            ...q,
            [key]: value,
          },
        },
        { skipEmptyString: true }
      );
      window.location.href = url
    },
    [location]
  );

  return { addQuery };
}
// Usage
const { addQuery } = useAddQuery()
addQuery('page', 2)

如果你使用react和react-router

export function useAddQuery() {
  const location = useLocation();
  const history = useHistory();

  const addQuery = useCallback(
    (key, value) => {
      let pathname = location.pathname;
      let searchParams = new URLSearchParams(location.search);
      searchParams.set(key, value);
      history.push({
        pathname: pathname,
        search: searchParams.toString()
      });
    },
    [location, history]
  );

  return { addQuery };
}

// Usage
const { addQuery } = useAddQuery()
addQuery('page', 2)

PS: qs是从query-string模块导入的。

我的解决方案:

const setParams = (data) => {
    if (typeof data !== 'undefined' && typeof data !== 'object') {
        return
    }

    let url = new URL(window.location.href)
    const params = new URLSearchParams(url.search)

    for (const key of Object.keys(data)) {
        if (data[key] == 0) {
            params.delete(key)
        } else {
            params.set(key, data[key])
        }
    }

    url.search = params
    url = url.toString()
    window.history.replaceState({ url: url }, null, url)
}

然后调用“setParams”并传递一个带有你想设置的数据的对象。

例子:

$('select').on('change', e => {
    const $this = $(e.currentTarget)
    setParams({ $this.attr('name'): $this.val() })
})

在我的情况下,我必须更新html选择输入时,它的变化,如果值是“0”,删除参数。如果对象键为“null”,则可以编辑该函数并从url中删除参数。

希望这对你们有帮助

这是对苏乔伊回答的另一种说法。刚刚改变了变量名,并添加了一个命名空间包装:

window.MyNamespace = window.MyNamespace  || {};
window.MyNamespace.Uri = window.MyNamespace.Uri || {};

(function (ns) {

    ns.SetQueryStringParameter = function(url, parameterName, parameterValue) {

        var otherQueryStringParameters = "";

        var urlParts = url.split("?");

        var baseUrl = urlParts[0];
        var queryString = urlParts[1];

        var itemSeparator = "";
        if (queryString) {

            var queryStringParts = queryString.split("&");

            for (var i = 0; i < queryStringParts.length; i++){

                if(queryStringParts[i].split('=')[0] != parameterName){

                    otherQueryStringParameters += itemSeparator + queryStringParts[i];
                    itemSeparator = "&";
                }
            }
        }

        var newQueryStringParameter = itemSeparator + parameterName + "=" + parameterValue;

        return baseUrl + "?" + otherQueryStringParameters + newQueryStringParameter;
    };

})(window.MyNamespace.Uri);

现在的用法是:

var changedUrl = MyNamespace.Uri.SetQueryStringParameter(originalUrl, "CarType", "Ford");