쿼리 문자열 매개 변수를 추가하거나 업데이트하려면 어떻게합니까?


364

javascript를 사용하여 URL에 쿼리 문자열 매개 변수를 추가하거나 존재하지 않는 경우 현재 값을 업데이트하려면 어떻게해야합니까? 클라이언트 측 개발에 jquery를 사용하고 있습니다.


1
내 경력에 비해 JavaScript로 "parseQueryString"함수를 100 번 정도 작성한 것 같습니다. 어렵지 않습니다. 요점 String#split은 최대 분할에 대한 두 번째 매개 변수를 사용합니다. jQuery map도 도움이 될 것입니다.
jpsimons

이 SO 게시물에는 많은 솔루션이 있습니다 stackoverflow.com/questions/1090948/…
Dilip Rajkumar

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
[?|&]해야[?&]
소주

8
var구분자 선언 바로 앞에 추가하여 구분자 변수 범위를 로컬 함수로 제한하십시오 .
Andrea Salicetti

3
value = encodeURIComponent(value);첫 줄을 추가해야 합니다. 그렇지 않으면 줄 바꿈이 올바르게 이스케이프되지 않습니다.
Felix

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가 제안한 것처럼-값을 조정하여 0 값을 설정할 수 있도록 undefined 및 null을 검사합니다.

세번째 업데이트

해시 태그 바로 앞에 querystring 변수를 제거하면 수정 된 해시 태그 기호가 손실되는 버그가있었습니다.

네 번째 업데이트

첫 번째 RegExp 객체에서 정규식 최적화를 지적한 @rooby에게 감사드립니다. @YonatanKarni가 찾은 (\? | &) 사용 문제로 인해 초기 정규 표현식을 ([? &])로 설정하십시오.

다섯 번째 업데이트

if / else 문에서 해시 var 선언 제거


5
단지의 'truthiness'를 확인하는 것은 value당신이 그렇게 대신 0으로 자신의 가치를 설정하면이 쿼리 문자열에서 변수를 제거하게됩니다 if (value) {}사용한다if (typeOf value !== 'undefined' && value !== null) {}
재론 Barends

1
정규식에서 ([? | &])은 ([? &])이어야합니다
rooby

이것이 원래의 솔루션에서 어떻게
이뤄졌

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

이제 존재 여부 foobar관계없이 설정되었습니다 .

그러나 위의 할당으로 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에서만 사용 중이므로 열악합니다. 폴리 필 을 사용하기로 결정한 경우 폴리 필 과 함께 사용하십시오.

업데이트 : 원래 답변 이후 브라우저 지원이 향상되었습니다.


polly fill은 좋지 않습니다 Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference . 즉 , 11 에서 오류가 발생합니다. 폴백으로 작동하지 않으면 pollyfill이 아닙니다.
Val

6
2019 업데이트 : 브라우저 지원은 이제 IE 및 일부 소형 모바일 브라우저를 제외한 대부분의 브라우저에 적합합니다. ungap의 새로운 pollyfill은 다음과 같이 쉽게 다룹니다 : 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
다른 답변에 대한 의견에서 지적했듯이 [?|&]그냥 있어야합니다 [?&](그렇지 않으면 일치합니다 |).
bonger

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
트위터는 더 이상 해시를 수정하지 않습니다! 해시가 종료되었습니다. History API를 환영합니다 !
Alba Mendez

죽지 않았다. 레거시 브라우저 호환성이 걱정되지 않는 환상적인 꿈의 나라에 살고 있다고 생각합니다. 이것은 당신에게 해당 될 수 있지만, 확실히 우리의 나머지 부분 (또는 실제로는 우리 대다수)에게는 해당되지 않습니다. 아마도 죽어가는 것이 더 적절할 것입니다.
AaronHS

1
1 년 후, IE 9
Douglas를

11

설정되지 않았거나 새 값으로 업데이트하려는 경우 다음을 사용할 수 있습니다.

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

그건 그렇고, 간단한 자바 스크립트입니다.

편집하다

jquery query-object plugin 을 사용해보십시오.

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


1
그러나 URL에 다른 쿼리 문자열 매개 변수는 유지되지 않습니다.
아마추어

당신이 옳습니다, 사과드립니다 .. 업데이트로, 나는 또 다른 옵션을 내 대답에 추가했습니다 :)
tradyblix

값을 재설정하지 않기 때문에 작동하지 않습니다. "추가 또는 업데이트"
Paolo Falomo

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
이것은 URL 파서로 DOM을 사용하여 정말 좋고 견고한 테스트 사례입니다. 그래도 example.com/?param=val& => example.com/?param=val&&new=key --double & and example.com/team => example.com/team?new=key 두 가지 경우를 찾았습니다 . team /? new = key / team? new = key를 / team /로 리디렉션하면 쿼리가 손실됩니다.
Timar Ivo Batis

1
실패한 테스트 사례에 감사드립니다. 나는 바이올린을 업데이트했다. 첫 번째는 힘들다. 기능 수정 방법에 대한 아이디어가 있습니까? 두 번째는 문제없이 처리되어야하며 이미 테스트 스위트에서 다룹니다. 어쩌면 나는 당신을 이해하지 못할 수도 있습니다. 보고있는 것을 시연하기 위해 시험 바이올린을 자유롭게 포크하십시오.
Dominic P

내가 만난 몇 가지 테스트 사례와 해결 방법을 추가했습니다. 가능한 한 DOM을 사용하려고했습니다. 기본적으로 동일한 도메인 내의 상대 링크에도 작동하려면 이것이 필요했습니다. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis

1
@ braed 브라우저에 무거운 리프팅을 남기기 때문에 접근 방식이 마음에 듭니다. 여기에 많은 답변에서 볼 수 있듯이이 문제는 간단하지 않습니다. 솔루션이 다루어야 할 코너 사례가 많이 있습니다. DOM을 활용하면 대부분 무료로 제공됩니다.
Dominic P

1
@ braed는 대답에 링크 된 테스트 스위트를 살펴보십시오. 여기에 DOM에 의존하지 않는 많은 솔루션은 나열된 모든 최신 사례를 설명하지 않기 때문에 실패합니다. 읽을 때 node.js 의 URL 모듈 을 보는 것이 도움이 될 수 있습니다. 직접 관련이 없지만 URL 문자열과 관련된 복잡성에 대한 아이디어를 제공합니다.
Dominic P

9

내 접근 방식은 다음과 같습니다. location.params()함수 (아래 표시)를 getter 또는 setter로 사용할 수 있습니다. 예 :

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

또한 도미닉 P에 의해 적지을 testcases 실패 stackoverflow.com/a/23529943/8385841
Timar에게 이보 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

여기에서 내 테이크 ( "use strict"와 호환; 실제로 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

Stylistic quibble : 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 답변을 기반으로하지만 많은 개선 사항이 있습니다.


2

ES6 및 jQuery를 사용하여 기존 URL에 매개 변수 목록을 추가하는 코드 :

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 끝에 'hash'앵커와 여러 물음표 문자 (?)를 지원합니다. 정규식 접근법보다 약간 빠릅니다.

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

이 함수를 사용하여 jquery를 기반으로 URL에서 쿼리 문자열 매개 변수를 추가, 제거 및 수정하십시오.

/**
@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.searchGal 및 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 (actualy sizzle) 및 C # magick를 작업했습니다.

그래서 나는 서버가 전달 된 값으로 작업을 마친 후에는 더 이상 가치가 중요하지 않다는 것을 깨달았습니다. 동일한 매개 변수가 전달됩니다. 그리고 그것은 모든 클라이언트 측이므로 일부 캐싱 / 쿠키 등은 그 점에서 시원 할 수 있습니다.

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>

씨#:

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

좋아 비판은 환영합니다 (이것은 야간 칵테일이므로 조정 사항에 유의하십시오). 이것이 도움이 되었으면 엄지 손가락으로 표시하십시오.

중복은 없으며, 각 요청은 수정 한대로 고유하며, 요청이 구조적으로 구성되어 있기 때문에 DOM에서 동적으로 더 많은 쿼리를 쉽게 추가 할 수 있습니다.


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

@amateur와 동일한 기능

jslint에서 오류가 발생하면 for 루프 뒤에 이것을 추가하십시오.

if(params.hasOwnProperty(key))

해시 또는 값 ( http://abc.def/?a&b&c)이 할당되지 않은 매개 변수를 처리하지 않습니다 .
Adam Leggett

0

이 페이지에는 어색하고 불필요하게 복잡한 답변이 많이 있습니다. @Amateur의 최고 등급은 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] || '');
  }
}

2
이것은 마지막 함수에서 빠진 대괄호입니다. var matchData = uri.match (/^([^#]*)(#.*)?$/
Jammer

separator에 정의되어 있지 않습니다 updateQueryStringParamsNoHash. 에서 updateQueryStringParameter바꾸려는 매개 변수에 값 (예 :)이 지정되지 않으면 모든 것이 고장납니다 http://abc.def/?a&b&c.
Adam Leggett

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("&");
}   
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.