Як я можу додати або оновити параметр рядка запиту?


364

Як за допомогою JavaScript можна додати параметр рядка запиту до URL-адреси, якщо його немає, або якщо він присутній, оновити поточне значення? Я використовую jquery для розвитку свого клієнта.


1
Схоже, я написав функцію «parseQueryString» в JavaScript приблизно 100 разів за свою кар’єру. Це не важко. Ключові моменти, String#splitприймає другий параметр для максимуму розбиття. jQuery mapтакож буде корисним.
jpsimons

Цей пост також має багато рішень stackoverflow.com/questions/1090948/…
Діліп Райкумар

1
Деякі люди сприймають це запитання і означають "як змінити URL-адресу в адресному рядку", а інші "як змінити будь-яку змінну URL-адреси"
PandaWood

Відповіді:


468

Я написав таку функцію, яка виконує те, що я хочу досягти:

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
Ця відповідь не працює, коли в URI є хеш - рядки запиту повинні бути розміщені перед хешем, інакше вони не надсилаються на сервер. jsfiddle.net/4yXzR
Грег

20
[?|&]повинно бути[?&]
soju

8
Обмежте масштабування змінної роздільника на локальну функцію, додавши varбезпосередньо перед декларацією сепаратора.
Андреа Салікетті

3
Я думаю, ви повинні додати value = encodeURIComponent(value);в першому рядку, інакше розриви рядків не будуть усунені правильно.
Фелікс

18
Це також піклується про хеш: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz

189

Я розширив рішення та поєднав його з іншим, який знайшов замінити / оновити / видалити параметри запитів на основі введення користувачів та врахування якоря 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 - перевірити значення Tweak, щоб перевірити, чи не визначено та null, щоб дозволити встановлення 0 значень

Третє оновлення

Виникла помилка, коли видалення змінної запиту безпосередньо перед хештегом втратить символ хештега, який було виправлено

Четверте оновлення

Дякуємо @rooby за вказівку оптимізації регексу в першому об'єкті RegExp. Встановіть початковий регулярний вираз на ([? &]) Через проблему з використанням (\? | &), Знайденого @YonatanKarni

П'яте оновлення

Видалення оголошення оголошень хеша у операторі if / else


5
Щойно перевірка «правдивості» valueцього приводу призведе до видалення змінних із рядка запитів, коли ви встановите їх значення 0. Так що замість if (value) {}вас слід використовуватиif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends,

1
У RegExp ([? | &]) Дійсно має бути ([? &])
rooby

Смішно, як це перенесли з оригінального рішення - також могли використовувати (\? | &)
ellemayo

1
отримання винятку "недійсний регулярний виняток / недійсна група" для створення регулярних виразів у хромованій версії 31.0.1650.63, вирішених поверненням початку "([? &])"
Yonatan Karni

1
Не те, що це має значення, крім мене як OCD, але змінна hashоголошується двічі;)
wlingke

117

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 , якщо ви вирішите використовувати його.

Оновлення: Підтримка браузера покращилася з моєї оригінальної відповіді.


polly fill, це не добре, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference на ie11 ви отримуєте цю помилку. це не завулок, якщо він не працює як резервний.
Валь

6
Оновлення 2019 року : Підтримка браузера тепер хороша для більшості браузерів, крім IE та деяких невеликих мобільних браузерів. Новий заповнювач ungap легко охоплює: github.com/ungap/url-search-params
Фліон

Ідеальна відповідь, однак він не справляється з випадковою справою, коли в URL-адресі присутній хештег. Просте додавання хешу до кінця newRelativePathQueryробить трюк:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec

43

На основі відповіді @ 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');
    } 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/bp3tmuxh/1/


2
Значно чистіше. FYI для кутових користувачів маршрутизатора, які можуть мати "?" і в хеші. Переміщення var separatorрядка праворуч над поверненням виправляє помилку з "/ app # / cool? Fun = true". Це вибрало б "&" як роздільник, хоча ще немає реальних парамєнтів рядка запиту. Тільки клієнтські.
j_walker_dev

3
Як зазначалося в коментарях до інших відповідей, [?|&]слід бути справедливим [?&](інакше буде відповідати |).
Бонгер

1
Так, "([?|&])"це не добре. Виправте це як var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");або var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(приємне розширення іншими способами!)
YakovL

ок, вибачте, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");не працює, другий
YakovL

Схоже, що ця версія не підтримує видалення параметра рядка запиту, опустивши значення. Чи правий я?
jkupczak


11

window.location.search читається / записується.

Однак зміна рядка запиту перенаправить сторінку, на якій ви перебуваєте, і призведе до оновлення з сервера.

Якщо ви намагаєтеся зберегти стан клієнта (і, можливо, зробити його закладкою), ви захочете змінити хеш URL-адреси замість рядка запиту, який зберігатиме вас на одній сторінці (window.location). хеш читається / пише). Саме так роблять такі веб-сайти, як twitter.com.

Також ви хочете, щоб кнопка "Назад" спрацювала, вам доведеться прив'язувати події javascript до події зміни хешу, хорошим плагіном для цього є http://benalman.com/projects/jquery-hashchange-plugin/


4
Twitter більше не змінює хеш! Хеш мертвий, вітаємо API історії !
Альба Мендес

це далеко не мертве. я думаю, ви живете в чарівної країні мрій, де сумісна версія браузера не викликає жодних проблем. це може статися для вас, але це, звичайно, не для решти нас (або насправді більшості з нас). можливо, померти доречніше ...
AaronHS

1
Через рік, схоже, єдиний напівновіший браузер, який не підтримує це IE 9
Douglas.Sesar

11

Якщо це не встановлено або потрібно оновити новим значенням, ви можете використовувати:

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

Це, до речі, у простому Javascript.

EDIT

Ви можете спробувати використати плагін jquery query-object

window.location.search = jQuery.query.set ("парам", 5);


1
це не буде підтримувати будь-які інші параметри рядка запиту в URL-адресі.
аматорський

Ви маєте рацію, вибачаюся .. як оновлення, я додав ще один варіант до своєї відповіді :)
tradyblix

Це не працює, оскільки не скидає значення. "додати або оновити"
Паоло Фаломо

11

Я усвідомлюю, що це питання давнє і на нього відповіли смертю, але ось у мене це питання. Я намагаюся тут винаходити колесо, тому що я нещодавно використовував відповідь і неправильне поводження з фрагментами 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;
}

2
Це виглядає дуже добре, надійні тестові випадки + використання DOM як аналізатор URL-адрес. Однак я виявив два випадки: example.com/?param=val& => example.com/?param=val&&new=key --double & і example.com/team => example.com/team?new=key очікується: team /? new = ключ деякого переадресації / team? new = ключ до / team / і запити втрачаються.
Тимар Іво Батіс

1
Дякуємо за невдалий тестовий випадок. Я оновив скрипку. Цей перший важкий. Будь-які ідеї, як виправити функцію для неї? Друге не повинно працювати з проблемою і вже охоплене тестовим набором. Можливо, я вас теж не розумію. Не соромтеся роздрібнити тестову скрипку, щоб продемонструвати те, що ви бачите.
Домінік П

Я додав кілька тестових випадків, в які я натрапив і вирішував проблеми. Я намагався максимально використовувати DOM. В першу чергу мені це було потрібно, щоб також працювати для відносних посилань в одному домені. jsfiddle.net/Timar/7sjrhbm3
Іво Батіс

1
@braed Мені подобається такий підхід, оскільки він залишає важкий підйом для браузера. Як ви бачите з безлічі відповідей тут, ця проблема не така проста, як здається. Існує багато кутових справ, які потрібно вирішити. Більшість із них покриваються безкоштовно, коли ви користуєтеся DOM.
Домінік П

1
@braed обов'язково погляньте на тестовий набір, який я пов’язав у відповіді. Тут багато рішень, які не покладаються на DOM, виходять з ладу, оскільки вони не враховують усіх перелічених випадків. Щодо читання, можливо, буде доцільно переглянути URL-модуль для node.js. Це не пов'язано безпосередньо, але це дає уявлення про деякі складності, пов'язані з рядками URL.
Домінік П

9

Ось мій підхід: location.params() функцію (показану нижче) можна використовувати як геттер або сетер. Приклади:

Враховуючи URL-адресу http://example.com/?foo=bar&baz#some-hash,

  1. location.params() поверне об’єкт з усіма параметрами запиту: {foo: 'bar', baz: true} .
  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('&');
};

6

Це моє уподобання, і воно охоплює випадки, про які я можу придумати. Чи може хтось придумати спосіб звести його до єдиної заміни?

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

Також не вистачає кількох випробувань Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis

5

Я знаю, що це досить старе, але я хочу запустити свою робочу версію тут.

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



2

Моє взяття звідси (сумісне з "використовувати строгий"; насправді не використовує 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()));
});

2

На основі відповіді @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

Стилістична приказка: typeof value !== 'undefined' && value !== nullбільш явна, але value != nullозначає те саме і більш лаконічна.
епсілон

2

Ось більш коротка версія, про яку піклуються

  • запит із заданим параметром або без нього
  • запит із кількома значеннями параметрів
  • запит, що містить хеш

Код:

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, але з багатьма вдосконаленнями.


2

Код, який додає список параметрів до існуючої URL-адреси за допомогою ES6 та 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 схожий

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

1

Інший підхід без використання регулярних виразів . Підтримує «хеш-анкери» в кінці 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
}

1

Використовуйте цю функцію для додавання, видалення та зміни параметру рядка запиту з URL-адреси на основі 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];
    }
}

Додайте новий і змініть існуючий параметр до 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

1

Використовуючи 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/


0

Щоб навести приклад коду для модифікації, window.location.searchяк запропоновано Gal та 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

Код сценарію 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;
                }
            })
        });

0

Так, у мене виникла проблема, коли мій запит переповнюватиметься та дублюватиметься, але це було пов’язано з моєю власною млявістю. тому я трохи грав і опрацював js jquery (фактично шиплячий) та 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.
          }
      }
  }

Гаразд критики вітається (це була нічна страждання, тому сміливо відзначайте коригування). Якщо це зовсім допомогло, проведіть пальцем вгору, Happy Coding.

Немає дублікатів, кожен запит настільки унікальний, як ви його змінили, і завдяки тому, як це структуровано, легко додавати більше запитів, що динамічно додаються з дому.


0

Ось альтернативний метод з використанням вбудованих властивостей елемента якоря 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;
	};


0

якщо ви хочете встановити кілька параметрів одночасно:

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

така ж функція, як @ аматорські

якщо jslint дає вам помилку, додайте це після циклу for

if(params.hasOwnProperty(key))

Не обробляє хеші або параметри, яким не призначено значення ( http://abc.def/?a&b&c).
Адам Леггетт

0

На цій сторінці є безліч незручних і зайво складних відповідей. Найвищий рейтинг, @ любительський, досить хороший, хоча у 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це не рядок, ви не отримаєте помилок при спробі дзвонити matchабоreplace в тому, що може не реалізувати ці методи.

І якщо ви хочете обробити випадок хешу (і ви вже зробили перевірку на правильний формат 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;
}

Або ви можете внести невеликі зміни в відмінну відповідь @ Адама:

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
Це відсутня дужка в останній функції: var matchData = uri.match (/^( evidence^#Sense*)(#.*)?$/
Jammer

separatorне визначено в updateQueryStringParamsNoHash. У updateQueryStringParameterвсьому виходить з ладу, якщо параметру, який ви замінюєте, не присвоєно значення (наприклад http://abc.def/?a&b&c).
Адам Леггетт

0

Це повинно служити цілі:

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("&");
}   
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.