How can I add or update a query string parameter?

后端 未结 27 2869
别那么骄傲
别那么骄傲 2020-11-22 02:35

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

相关标签:
27条回答
  • 2020-11-22 03:15

    My take from here (compatible with "use strict"; does not really use 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);
    }
    

    Example usage:

    // 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()));
    });
    
    0 讨论(0)
  • 2020-11-22 03:16

    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:

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

    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.

    function updateQueryStringParameter(uri, key, value) {
      var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
      if( value === undefined ) {
        if (uri.match(re)) {
            return uri.replace(re, '$1$2');
        } 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;
      }
      }  
    }
    

    See it in action at https://jsfiddle.net/bp3tmuxh/1/

    0 讨论(0)
  • 2020-11-22 03:16

    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.

    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 suite for it (or other similar functions). If a function can pass every one of the tests there, I say it's probably good to go.

    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.

    /**
     * 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;
    }
    
    0 讨论(0)
  • 2020-11-22 03:17

    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, '$1' + key + "=" + value + '$2');
      }
      else {
        return uri + separator + key + "=" + value;
      }
    }
    
    0 讨论(0)
  • 2020-11-22 03:17

    Code that appends a list of parameters to an existing url using ES6 and jQuery:

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

    Where listOfParams is like

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

    Example of Usage:

        UrlBuilder.appendParametersToUrl(urlBase, listOfParams);
    

    Fast tests:

        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
    
    0 讨论(0)
  • 2020-11-22 03:19

    Here is a shorter version that takes care of

    • query with or without a given parameter
    • query with multiple parameter values
    • query containing hash

    Code:

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

    The regex description can be found here.

    NOTE: This solution is based on @amateur answer, but with many improvements.

    0 讨论(0)
提交回复
热议问题