Làm cách nào để thêm hoặc cập nhật tham số chuỗi truy vấn?


364

Với javascript, làm cách nào tôi có thể thêm tham số chuỗi truy vấn vào url nếu không có hoặc nếu có, cập nhật giá trị hiện tại? Tôi đang sử dụng jquery cho sự phát triển phía khách hàng của tôi.


1
Có vẻ như tôi đã viết hàm "parseQueryString" trong JavaScript khoảng 100 lần trong sự nghiệp của mình. Nó không khó. Các điểm chính, String#splitlấy tham số thứ hai để chia tối đa. jQuery mapcũng sẽ hữu ích.
jpsimons

Bài đăng SO này cũng có nhiều giải pháp stackoverflow.com/questions/1090948/ từ
Dilip Rajkumar

1
Một số người đang đặt câu hỏi này có nghĩa là "cách thay đổi URL trong thanh địa chỉ" và những người khác "làm thế nào để thay đổi bất kỳ biến URL nào"
PandaWood

Câu trả lời:


468

Tôi đã viết các chức năng sau đây để thực hiện những gì tôi muốn đạt được:

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

36
Câu trả lời này không hoạt động khi có một hàm băm trong URI - các chuỗi truy vấn phải được đặt trước hàm băm, nếu không chúng sẽ không được gửi đến máy chủ. jsfiddle.net/4yXzR
Greg

20
[?|&]nên là[?&]
soju

8
Giới hạn biến dải phân cách phạm vi chức năng cục bộ bằng cách thêm varngay trước khi khai báo dấu tách.
Andrea Salicetti

3
Tôi nghĩ rằng, bạn nên thêm value = encodeURIComponent(value);vào dòng đầu tiên, nếu không thì ngắt dòng không được thoát chính xác.
Felix

18
Điều này cũng sẽ chăm sóc hàm băm: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz

189

Tôi đã mở rộng giải pháp và kết hợp nó với một giải pháp khác mà tôi thấy để thay thế / cập nhật / xóa các tham số chuỗi truy vấn dựa trên đầu vào của người dùng và xem xét các url url.

Không cung cấp một giá trị sẽ loại bỏ tham số, cung cấp một giá trị sẽ thêm / cập nhật tham số. Nếu không có URL nào được cung cấp, nó sẽ được lấy từ 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;
        }
    }
}

Cập nhật

Có một lỗi khi xóa tham số đầu tiên trong chuỗi truy vấn, tôi đã làm lại regex và kiểm tra để bao gồm một sửa chữa.

Cập nhật lần thứ hai

Theo đề xuất của @ JarónBarends - Kiểm tra giá trị tinh chỉnh để kiểm tra không xác định và null để cho phép đặt 0 giá trị

Cập nhật lần thứ ba

Có một lỗi trong đó loại bỏ biến chuỗi truy vấn trực tiếp trước khi hashtag sẽ mất biểu tượng hashtag đã được sửa

Cập nhật lần thứ tư

Cảm ơn @rooby đã chỉ ra tối ưu hóa regex trong đối tượng RegExp đầu tiên. Đặt regex ban đầu thành ([? &]) Do vấn đề với việc sử dụng (\? | &) Được tìm thấy bởi @YonatanKarni

Cập nhật thứ năm

Xóa khai báo var var trong câu lệnh if / other


5
Chỉ cần kiểm tra 'tính trung thực' valuesẽ khiến điều này loại bỏ các biến khỏi chuỗi truy vấn khi bạn đặt giá trị của chúng thành 0. vì vậy thay vì if (value) {}bạn nên sử dụngif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends

1
Trong RegExp ([? | &]) Nên thực sự là ([? &])
rooby

Thật buồn cười là cách mang từ giải pháp ban đầu - cũng có thể sử dụng (\? | &)
ellemayo

1
nhận được một ngoại lệ "nhóm ngoại lệ / nhóm không hợp lệ không hợp lệ" khi tạo regex trong phiên bản chrome 31.0.1650.63, được giải quyết bằng cách trả lại từ đầu là "([? &])"
Yonatan Karni

1
Không phải vấn đề này ngoại trừ tôi là OCD, nhưng biến hashđược khai báo hai lần;)
wlingke

117

Các URLSearchParams tiện ích có thể hữu ích cho điều này kết hợp với window.location.search. Ví dụ:

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

Bây giờ foođã được đặt thành barbất kể nó đã tồn tại hay chưa.

Tuy nhiên, việc gán ở trên window.location.searchsẽ gây ra tải trang, do đó, nếu không mong muốn, hãy sử dụng API Lịch sử như sau:

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

Bây giờ bạn không cần phải viết regex hoặc logic của riêng bạn để xử lý sự tồn tại có thể của các chuỗi truy vấn.

Tuy nhiên, hỗ trợ trình duyệt rất kém vì hiện đang thử nghiệm và chỉ được sử dụng trong các phiên bản gần đây của Chrome, Firefox, Safari, iOS Safari, Trình duyệt Android, Android Chrome và Opera. Sử dụng với polyfill nếu bạn quyết định sử dụng nó.

Cập nhật: Hỗ trợ trình duyệt đã được cải thiện kể từ câu trả lời ban đầu của tôi.


Polly điền, không tốt, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference trên eg11 bạn nhận được lỗi đó. nó không phải là một pollyfill nếu nó không hoạt động như một dự phòng.
Val

6
Cập nhật 2019 : Hỗ trợ trình duyệt hiện tốt cho hầu hết các trình duyệt ngoại trừ IE và một số trình duyệt di động nhỏ. Pollyfill mới của ungap dễ dàng bao gồm: github.com/ungap/url-search-params
Flion

Câu trả lời hoàn hảo, tuy nhiên nó không xử lý usecase khi hashtag có trong url. Phần bổ sung đơn giản của hàm băm đến cuối của newRelativePathQuerytrò lừa:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec

43

Dựa trên câu trả lời của @ nghiệp dư (và hiện đang kết hợp bản sửa lỗi từ bình luận @j_walker_dev), nhưng có tính đến nhận xét về thẻ băm trong url tôi sử dụng như sau:

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

Chỉnh sửa để sửa chữa [?|&]trong regex, tất nhiên sẽ được [?&]chỉ ra trong các ý kiến

Chỉnh sửa: Phiên bản thay thế để hỗ trợ xóa thông số URL là tốt. Tôi đã sử dụng value === undefinednhư là cách để chỉ ra loại bỏ. Có thể sử dụng value === falsehoặc thậm chí một thông số đầu vào riêng biệt như mong muốn.

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

Xem nó trong hành động tại https://jsfiddle.net/bp3tmuxh/1/


2
Sạch sẽ hơn nhiều. FYI cho người dùng ui-router góc có thể có "?" trong băm là tốt. Di chuyển var separatordòng sang phải phía trên phần trả về sẽ sửa một lỗi với "/ app # / cool? Fun = true". Điều này sẽ chọn "&" làm dấu phân cách mặc dù chưa có thông số chuỗi truy vấn thực sự nào. Chỉ những khách hàng.
j_walker_dev

3
Như đã chỉ ra trong các ý kiến ​​về các câu trả lời khác, [?|&]nên chỉ là [?&](nếu không sẽ phù hợp |).
bonger

1
Vâng, "([?|&])"không tốt. Vui lòng sửa lỗi này dưới dạng var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");hoặc var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(một phần mở rộng đẹp theo những cách khác!)
YakovL

ok, xin lỗi, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");không hoạt động, cái thứ hai thì có
YakovL

Có vẻ như phiên bản này không hỗ trợ xóa tham số chuỗi truy vấn bằng cách bỏ qua giá trị. Tôi có đúng không
jkupczak


12

Tôi nhận ra câu hỏi này đã cũ và đã được trả lời cho đến chết, nhưng đây là cú đâm của tôi vào nó. Tôi đang cố gắng phát minh lại bánh xe ở đây vì tôi đang sử dụng câu trả lời hiện được chấp nhận và việc xử lý sai các đoạn URL gần đây đã cắn tôi trong một dự án.

Các chức năng dưới đây. Nó khá dài, nhưng nó được làm để trở nên kiên cường nhất có thể. Tôi rất thích đề xuất để rút ngắn / cải thiện nó. Tôi kết hợp một bộ thử nghiệm jsFiddle nhỏ cho nó (hoặc các chức năng tương tự khác). Nếu một chức năng có thể vượt qua tất cả các bài kiểm tra ở đó, tôi nói có lẽ nó tốt để đi.

Cập nhật: Tôi đã tìm thấy một chức năng tuyệt vời để sử dụng DOM để phân tích URL , vì vậy tôi đã kết hợp kỹ thuật đó ở đây. Nó làm cho chức năng ngắn hơn và đáng tin cậy hơn. Đạo cụ cho tác giả của chức năng đó.

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

2
Điều này có vẻ thực sự tốt, các trường hợp kiểm tra chắc chắn + sử dụng DOM làm trình phân tích cú pháp URL. Mặc dù vậy, tôi đã tìm thấy hai trường hợp: example.com/?param=val& => example.com/?param=val&&new=key --double & và example.com/team => example.com/team?new=key dự kiến: team /? new = key some redirect / team? new = key to / team / và các truy vấn bị mất.
Timar Ivo Batis

1
Cảm ơn cho trường hợp thử nghiệm thất bại. Tôi đã cập nhật các fiddle. Đó là lần đầu tiên là khó khăn. Bất kỳ ý tưởng về cách sửa chữa các chức năng cho nó? Thứ hai nên được xử lý không có vấn đề và đã được bao phủ trong bộ thử nghiệm. Có lẽ tôi không hiểu bạn mặc dù. Hãy thoải mái rẽ nhánh thử nghiệm để chứng minh những gì bạn đang nhìn thấy.
Đaminh P

Tôi đã thêm một số trường hợp thử nghiệm tôi chạy vào và giải pháp. Tôi đã cố gắng sử dụng DOM càng nhiều càng tốt. Chủ yếu tôi cần điều này để làm việc cho các liên kết tương đối trong cùng một tên miền. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis

1
@braed Tôi thích cách tiếp cận vì nó để lại sự nặng nề cho trình duyệt. Như bạn thấy từ rất nhiều câu trả lời ở đây, vấn đề này không đơn giản như nó có vẻ. Có rất nhiều trường hợp góc mà một giải pháp cần phải bao gồm. Hầu hết trong số chúng được bảo hiểm miễn phí khi bạn tận dụng DOM.
Đaminh P

1
@braed chắc chắn chỉ cần xem bộ kiểm tra tôi đã liên kết trong câu trả lời. Rất nhiều giải pháp ở đây không dựa vào DOM đã thất bại vì chúng không giải thích cho tất cả các trường hợp cạnh được liệt kê. Đối với việc đọc, có thể nên xem mô-đun URL cho node.js. Nó không liên quan trực tiếp, nhưng nó cho bạn ý tưởng về một số sự phức tạp liên quan đến chuỗi URL.
Đa Minh P

11

window.location.search là đọc / ghi.

Tuy nhiên - sửa đổi chuỗi truy vấn sẽ chuyển hướng trang bạn đang truy cập và gây ra làm mới từ máy chủ.

Nếu những gì bạn đang cố gắng làm là duy trì trạng thái phía máy khách (và có khả năng làm cho nó có thể đánh dấu trang), bạn sẽ muốn sửa đổi hàm băm URL thay vì chuỗi truy vấn, điều này giữ bạn trên cùng một trang (window.location. băm là đọc / ghi). Đây là cách các trang web như twitter.com làm điều này.

Bạn cũng muốn nút quay lại hoạt động, bạn sẽ phải liên kết các sự kiện javascript với sự kiện thay đổi băm, một plugin tốt cho điều đó là http://benalman.com/projects/jquery-hashchange-plugin/


4
Twitter không còn sửa đổi băm! Hash đã chết, chào mừng API Lịch sử !
Alba Mendez

nó còn lâu mới chết Tôi nghĩ rằng bạn đang sống trong một vùng đất mơ mộng huyền diệu nơi khả năng tương thích trình duyệt cũ không phải lo ngại. đây có thể là trường hợp của bạn, nhưng chắc chắn đó không phải là trường hợp của phần còn lại của chúng tôi (hoặc trên thực tế là phần lớn chúng ta). có lẽ chết là thích hợp hơn ...
AaronHS

1
Một năm sau, có vẻ như trình duyệt bán gần đây duy nhất không hỗ trợ đó là IE 9
Douglas.Sesar

11

Nếu nó không được đặt hoặc muốn cập nhật với một giá trị mới, bạn có thể sử dụng:

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

Bằng cách này, trong Javascript đơn giản.

BIÊN TẬP

Bạn có thể muốn thử sử dụng plugin đối tượng truy vấn jquery

window.location.search = jQuery.query.set ("param", 5);


1
điều này sẽ không duy trì bất kỳ tham số chuỗi truy vấn nào khác trên url.
nghiệp dư

bạn nói đúng, tôi xin lỗi .. như một bản cập nhật, tôi đã thêm một tùy chọn khác vào câu trả lời của mình :)
tradyblix

Điều này không hoạt động, bởi vì nó không thiết lập lại một giá trị. "thêm hoặc cập nhật"
Paolo Falomo

9

Đây là cách tiếp cận của tôi: location.params() Hàm (hiển thị bên dưới) có thể được sử dụng như một getter hoặc setter. Ví dụ:

Cho URL là http://example.com/?foo=bar&baz#some-hash,

  1. location.params()sẽ trả về một đối tượng có tất cả các tham số truy vấn : {foo: 'bar', baz: true}.
  2. location.params('foo')sẽ trở lại 'bar'.
  3. location.params({foo: undefined, hello: 'world', test: true})sẽ thay đổi URL thành http://example.com/?baz&hello=world&test#some-hash.

Đây là params()chức năng, có thể tùy ý được gán cho window.locationđối tượng.

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

6

Đây là sở thích của tôi, và nó bao gồm các trường hợp tôi có thể nghĩ ra. Bất cứ ai cũng có thể nghĩ ra một cách để giảm nó xuống một thay thế duy nhất?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}

Cũng thất bại khá nhiều thử nghiệm bởi Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis

5

Tôi biết cái này khá cũ nhưng tôi muốn sử dụng phiên bản làm việc của mình ở đây.

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>

LƯU Ý Đây là phiên bản sửa đổi của @elreimundo



2

Tôi lấy từ đây (tương thích với "sử dụng nghiêm ngặt"; không thực sự sử dụng 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);
}

Ví dụ sử dụng:

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

2

Dựa trên câu trả lời mà @ellemayo đưa ra, tôi đã đưa ra giải pháp sau đây cho phép vô hiệu hóa thẻ băm nếu muốn:

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

Gọi nó như thế này:

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

Kết quả trong:

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

Phân biệt phong cách: typeof value !== 'undefined' && value !== nullrõ ràng hơn, nhưng value != nullcó nghĩa là điều tương tự và ngắn gọn hơn.
eppsilon

2

Đây là một phiên bản ngắn hơn chăm sóc

  • truy vấn có hoặc không có tham số đã cho
  • truy vấn với nhiều giá trị tham số
  • truy vấn có chứa băm

Mã số:

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

Các regex mô tả có thể được tìm thấy ở đây .

LƯU Ý : Giải pháp này dựa trên câu trả lời @am Nghiệp, nhưng có nhiều cải tiến.


2

Mã nối thêm danh sách các tham số vào url hiện có bằng ES6 và 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;
    }
}

ListOfParams giống như thế nào

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

Ví dụ về cách sử dụng:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Kiểm tra nhanh:

    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

1

Một cách tiếp cận khác nhau mà không sử dụng các biểu thức thông thường . Hỗ trợ các neo 'băm' ở cuối url cũng như nhiều ký tự dấu chấm hỏi (?). Nên nhanh hơn một chút so với cách tiếp cận biểu thức thông thường.

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
}

1

Sử dụng chức năng này để thêm, xóa và sửa đổi tham số chuỗi truy vấn khỏi URL dựa trên jquery

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

Thêm mới và sửa đổi tham số hiện có vào url

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

Xóa hiện tại

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

1

Bằng cách sử dụng jQuerychúng ta có thể làm như dưới đây

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

Trong biến new_urlchúng ta sẽ có các tham số truy vấn mới.

Tham khảo: http://api.jquery.com/jquery.param/


0

Để đưa ra một ví dụ mã để sửa đổi window.location.searchtheo đề xuất của Gal và tradyblix:

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;

0

Mã script Java để tìm một chuỗi truy vấn cụ thể và thay thế giá trị của nó *

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

0

Vâng, tôi có một vấn đề trong đó chuỗi truy vấn của tôi sẽ bị tràn và trùng lặp, nhưng điều này là do sự chậm chạp của chính tôi. Vì vậy, tôi đã chơi một chút và làm việc với một số js jquery (sizzle thực tế) và C # magick.

Vì vậy, tôi mới nhận ra rằng sau khi máy chủ thực hiện với các giá trị đã qua, các giá trị không còn quan trọng nữa, không có việc sử dụng lại, nếu khách hàng muốn làm điều tương tự thì rõ ràng nó sẽ luôn là một yêu cầu mới, ngay cả khi đó là cùng tham số được thông qua. Và đó là tất cả các máy khách, vì vậy một số bộ nhớ cache / cookie, vv có thể được làm mát về vấn đề đó.

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

Được rồi, những lời chỉ trích được hoan nghênh (đây là một pha chế hàng đêm vì vậy hãy lưu ý điều chỉnh). Nếu điều này có ích gì cả, hãy đưa nó lên, Happy Coding.

Không trùng lặp, mỗi yêu cầu là duy nhất khi bạn sửa đổi nó và do cách thức này được cấu trúc, dễ dàng thêm nhiều truy vấn động từ wthin dom.


0

Đây là một phương pháp thay thế bằng cách sử dụng các thuộc tính sẵn có của phần tử HTML neo:

  • Xử lý các thông số đa giá trị.
  • Không có rủi ro sửa đổi đoạn # hoặc bất cứ thứ gì ngoài chuỗi truy vấn.
  • Có thể dễ đọc hơn một chút? Nhưng nó dài hơn.

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


0

nếu bạn muốn đặt nhiều tham số cùng một lúc:

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

cùng chức năng như @ nghiệp dư

nếu jslint cung cấp cho bạn một lỗi, hãy thêm cái này sau vòng lặp for

if(params.hasOwnProperty(key))

Không xử lý băm hoặc tham số không được gán giá trị ( http://abc.def/?a&b&c).
Adam Leggett

0

Có rất nhiều câu trả lời lúng túng và phức tạp không cần thiết trên trang này. Người được đánh giá cao nhất, @ nghiệp dư, là khá tốt, mặc dù nó có một chút lông tơ không cần thiết trong RegExp. Đây là một giải pháp tối ưu hơn một chút với RegExp sạch hơn và một replacecuộc gọi sạch hơn :

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

Là một phần thưởng bổ sung, nếu urikhông phải là một chuỗi, bạn sẽ không gặp lỗi khi cố gắng gọi matchhoặc replacetrên một cái gì đó có thể không thực hiện các phương thức đó.

Và nếu bạn muốn xử lý trường hợp băm (và bạn đã thực hiện kiểm tra HTML được định dạng chính xác), bạn có thể tận dụng hàm hiện có thay vì viết một hàm mới có cùng logic:

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

Hoặc bạn có thể thực hiện một số thay đổi nhỏ đối với câu trả lời xuất sắc của @ 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] || '');
  }
}

2
Đây là một dấu ngoặc bị thiếu trong hàm cuối cùng: var matchData = uri.match (/ ^ ([^ ^ # *) (#
Jammer

separatorkhông được xác định trong updateQueryStringParamsNoHash. Trong updateQueryStringParameter, mọi thứ đều bị hỏng nếu tham số bạn thay thế không được gán giá trị (ví dụ http://abc.def/?a&b&c).
Adam Leggett

0

Điều này sẽ phục vụ mục đích:

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("&");
}   
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.