Как я могу добавить или обновить параметр строки запроса?

364

С помощью javascript, как я могу добавить параметр строки запроса в URL, если он отсутствует, или, если он присутствует, обновить текущее значение? Я использую jquery для разработки на стороне клиента.

любитель
источник
1
Похоже, что я написал функцию "parseQueryString" на JavaScript около 100 раз за свою карьеру. Это не сложно. Ключевые моменты, String#splitпринимает второй параметр для максимального разделения. jQuery's mapтакже будет полезен.
jpsimons
В этом посте также есть много решений stackoverflow.com/questions/1090948/…
Дилип Раджкумар
1
Некоторые люди воспринимают этот вопрос как «как изменить URL в адресной строке», а другие «как изменить любую переменную URL»
PandaWood
возможно дубликат stackoverflow.com/questions/486896/...
Пользователь

Ответы:

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
[?|&]должно быть[?&]
соджу
8
Ограничьте область видимости переменной разделителя локальной функцией, добавив ее varнепосредственно перед объявлением разделителя.
Андреа Саликетти
3
Я думаю, вы должны добавить value = encodeURIComponent(value);в первой строке, иначе разрывы строк не будут экранированы правильно.
Феликс
18
Это позаботится и о хэше: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Нияз
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 - проверка значения твика для проверки неопределенности и нулевого значения, позволяющего установить 0 значений

Третье обновление

Была ошибка, при которой удаление переменной строки запроса непосредственно перед тем, как хэштег потерял символ хештега, которое было исправлено

Четвертое обновление

Спасибо @rooby за указание на оптимизацию регулярных выражений в первом объекте RegExp. Установите начальное регулярное выражение в ([? &]) Из-за проблемы с использованием (\? | &), Найденной @YonatanKarni

Пятое обновление

Удаление объявления хеш-переменной в операторе if / else

ellemayo
источник
5
Просто проверка «истинности» valueприведет к удалению переменных из строки запроса, когда вы установите их значение на 0. Поэтому вместо if (value) {}вас следует использоватьif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends
1
В RegExp ([? | &]) Действительно должно быть ([? &])
rooby
Забавно, как это перенесено из оригинального решения - также можно использовать (\? | &)
ellemayo
1
получение исключения «недопустимое регулярное исключение / недопустимая группа» при создании регулярного выражения в chrome версии 31.0.1650.63, решается путем возврата начала в «([? &])»
Йонатан Карни
1
Не то, чтобы это hash
имело
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приведет к загрузке страницы, поэтому, если это нежелательно, используйте History 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 Browser, Android Chrome и Opera. Используйте с полифиллом, если вы решите его использовать.

Обновление: поддержка браузера улучшена с момента моего первоначального ответа.

Энтони Мэннинг-Франклин
источник
Полли заполнить, это не хорошо, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference на ie11 вы получаете эту ошибку. это не Pollyfill, если он не работает как запасной вариант.
Val
6
Обновление 2019 : поддержка браузеров теперь хороша для большинства браузеров, кроме IE и некоторых небольших мобильных браузеров. Новый pollyfill ungap легко покрывает это: github.com/ungap/url-search-params
Flion
Идеальный ответ, однако он не обрабатывает сценарий использования, когда в 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
Гораздо чище. К вашему сведению для пользователей угловых UI-маршрутизаторов, которые могут иметь "?" в хеше тоже. Перемещение 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
Похоже, что эта версия не поддерживает удаление параметра строки запроса путем пропуска значения. Я прав?
17
12

Я понимаю, что этот вопрос старый и на него уже дан ответ, но вот мой ответ. Я пытаюсь изобрести колесо здесь, потому что я использовал принятый в настоящее время ответ, а неправильная обработка фрагментов 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 ожидаемо: команда /? новый = ключ какой-то редирект / команда? новый = ключ / команда / и запросы потеряны.
Тимар Иво Батис,
1
Спасибо за провал теста. Я обновил скрипку. Этот первый жесткий. Любые идеи о том, как исправить функцию для него? Второе должно быть обработано без проблем и уже включено в набор тестов. Может быть, я не понимаю тебя, хотя Не стесняйтесь раскошелиться на тестовую скрипку, чтобы продемонстрировать, что вы видите.
Доминик П
Я добавил несколько тестовых случаев, с которыми столкнулся, и обходных путей. Я старался максимально использовать DOM. Прежде всего мне это нужно, чтобы работать для относительных ссылок в том же домене. jsfiddle.net/Timar/7sjrhbm3
Тимар Иво Батис
1
@braed Мне нравится подход, потому что он оставляет тяжелую работу для браузера. Как вы видите из множества ответов здесь, эта проблема не так проста, как кажется. Существует множество угловых случаев, которые необходимо решить. Большинство из них распространяется бесплатно, когда вы используете DOM.
Доминик П
1
@ Braed, конечно, просто посмотрите на набор тестов, который я связал в ответе. Многие решения здесь, которые не полагаются на DOM, терпят неудачу, потому что они не учитывают все перечисленные крайние случаи. Что касается чтения, может быть полезно посмотреть на модуль URL для node.js. Он не имеет прямого отношения, но дает представление о некоторых сложностях, связанных со строками URL.
Доминик П
11

window.location.search для чтения / записи.

Однако - изменение строки запроса перенаправит страницу, на которой вы находитесь, и приведет к обновлению с сервера.

Если вы пытаетесь сохранить состояние на стороне клиента (и, возможно, сделать его способным делать закладки), вы захотите изменить хеш URL вместо строки запроса, которая удерживает вас на той же странице (window.location. хэш читается / пишется). Вот как это делают такие сайты, как twitter.com.

Вы также захотите, чтобы кнопка «Назад» работала, вам нужно будет привязать события javascript к событию изменения хеша, хороший плагин для этого - http://benalman.com/projects/jquery-hashchange-plugin/

гал
источник
4
Твиттер больше не изменяет хэш! Хэш мертв, добро пожаловать в историю API !
Альба Мендес
это далеко от мертвых. Я думаю, вы живете в волшебной стране грез, где совместимость с устаревшими браузерами не имеет значения. это может иметь место для вас, но это, безусловно, не относится к остальным из нас (или на самом деле большинство из нас). возможно, умирание более уместно ...
AaronHS
1
Год спустя, похоже, что единственный браузер последнего времени, который не поддерживает его, это IE 9
Douglas.Sesar
11

Если он не установлен или вы хотите обновить его новым значением, вы можете использовать:

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

Это в простом Javascript, кстати.

РЕДАКТИРОВАТЬ

Вы можете попробовать использовать плагин jquery query-object

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

tradyblix
источник
1
это не будет поддерживать любые другие параметры строки запроса в URL, хотя.
любитель
Вы правы, я прошу прощения .. В качестве обновления я добавил еще один вариант в свой ответ :)
tradyblix
Это не работает, потому что не сбрасывает значение. «добавить или обновить»
Паоло Фаломо
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?");
}
Адам Леггетт
источник
Также не удается пройти немало тестов. Доминик Р stackoverflow.com/a/23529943/8385841
Тимар Иво Батис,
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.

Паоло Фаломо
источник
1
Протестировано с помощью jsFiddle от Доминика П: FAIL :: example.com ? :: example.com/?¶m=new Ожидается: example.com/?param=new FAIL :: example.com/?param :: example.com/?param¶m=new Ожидается: example.com/?param=new FAIL :: example.com/?param=&param2 :: example.com/?param=new&param2 Ожидается: example.com/?param=new¶m2 FAIL :: example.com/?param2=val¶m[]=val : : example.com/?param2=val¶m[]=val¶m=new Ожидается: example.com/?param2=val¶m[]=new
Тимар Иво Батис
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
RuubW
источник
Стилистическое толкование: typeof value !== 'undefined' && value !== nullболее явное, но value != nullозначает то же самое и более сжатое.
eppsilon
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, но со многими улучшениями.

MaxZoom
источник
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
}
cwills
источник
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/

anjaneyulubatta505
источник
0

Чтобы дать пример кода для модификации, window.location.searchкак предложено Галом и 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;
Risadinha
источник
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;
                }
            })
        });
Mohamed.Abdo
источник
0

Да, у меня была проблема, из-за которой моя строка запроса переполнялась и дублировалась, но это было связано с моей собственной медлительностью. так что я немного поиграл и работал над js jquery (на самом деле sizzle) и магией C #.

Так что я только что понял, что после того, как сервер завершил передачу значений, значения больше не имеют значения, повторного использования не будет, если клиент хочет сделать то же самое, очевидно, это всегда будет новый запрос, даже если его такие же параметры передаются. И это все на стороне клиента, так что некоторые кеширование / куки и т. Д. Может быть круто в этом отношении.

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.

Никаких дубликатов, каждый запрос настолько уникален, насколько вы его изменили, и благодаря тому, как это структурировано, легко добавлять больше запросов динамически изнутри dom.

LokizFenrir
источник
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;
	};

Glenns
источник
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;
}

та же функция, что и у @ amateur's

если jslint выдает ошибку, добавьте это после цикла for

if(params.hasOwnProperty(key))
Рашид О
источник
Не обрабатывает хэши или параметры, которым не присвоено значение ( http://abc.def/?a&b&c).
Адам Леггетт
0

На этой странице много неуклюжих и излишне сложных ответов. @ Amateur's с самым высоким рейтингом довольно хорош, хотя в 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;
}

Или вы можете внести небольшие изменения в отличный ответ @ 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] || '');
  }
}
elreimundo
источник
2
Это отсутствующая скобка в последней функции: var matchData = uri.match (/^([^#]*)(#.*)?$/
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("&");
}   
mmuzahid
источник