ฉันจะเพิ่มหรืออัปเดตพารามิเตอร์สตริงข้อความค้นหาได้อย่างไร


364

ด้วย javascript ฉันจะเพิ่มพารามิเตอร์สตริงข้อความค้นหาไปยัง URL ได้อย่างไรหากไม่มีอยู่หรือมีอยู่ให้อัปเดตค่าปัจจุบัน ฉันใช้ jquery เพื่อการพัฒนาด้านลูกค้าของฉัน


1
ดูเหมือนว่าฉันได้เขียนฟังก์ชัน "parseQueryString" ใน JavaScript ประมาณ 100 ครั้งในอาชีพของฉัน มันไม่ยาก จุดสำคัญString#splitใช้พารามิเตอร์ที่สองสำหรับการแยกสูงสุด jQuery's 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
Greg

20
[?|&]ควรจะเป็น[?&]
soju

8
กำหนดขอบเขตตัวแปรตัวคั่นไปยังฟังก์ชันโลคัลโดยเพิ่ม varก่อนการประกาศตัวคั่น
Andrea Salicetti

3
ฉันคิดว่าคุณควรเพิ่มvalue = encodeURIComponent(value);ในบรรทัดแรกมิฉะนั้นการขึ้นบรรทัดใหม่จะไม่สามารถหลบหนีได้อย่างถูกต้อง
เฟลิกซ์

18
สิ่งนี้จะดูแลแฮชเช่นกัน: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz

189

ฉันได้ขยายการแก้ปัญหาและรวมกับอื่นที่ฉันพบเพื่อแทนที่ / ปรับปรุง / ลบพารามิเตอร์การสืบค้นตามการป้อนข้อมูลของผู้ใช้และพิจารณา URL ที่ยึดเหนี่ยว

การไม่ส่งค่าจะเป็นการลบพารามิเตอร์การจัดหาจะเป็นการเพิ่ม / อัปเดตพารามิเตอร์ หากไม่มีการระบุ 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;
        }
    }
}

ปรับปรุง

มีข้อผิดพลาดเมื่อลบพารามิเตอร์แรกในการสืบค้นฉันได้ทำใหม่ regex และทดสอบเพื่อรวมการแก้ไข

ปรับปรุงที่สอง

ตามที่แนะนำโดย @ JarónBarends - การตรวจสอบค่า Tweak เพื่อตรวจสอบกับ undefined และ null เพื่ออนุญาตการตั้งค่า 0

ปรับปรุงที่สาม

มีข้อผิดพลาดที่การลบตัวแปรการสืบค้นโดยตรงก่อนที่แฮชแท็กจะสูญเสียสัญลักษณ์แฮชแท็กซึ่งได้รับการแก้ไขแล้ว

การปรับปรุงที่สี่

ขอบคุณ @rooby สำหรับการชี้ให้เห็นถึงการเพิ่มประสิทธิภาพ regex ในวัตถุ RegExp แรก ตั้งค่า regex เริ่มต้นเป็น ([? &]) เนื่องจากปัญหาการใช้ (\? | &) พบโดย @YonatanKarni

การปรับปรุงที่ห้า

การลบการประกาศ hash var ในคำสั่ง if / else


5
เพียงตรวจสอบ 'ความจริง' ของvalueจะทำให้สิ่งนี้เพื่อลบตัวแปรจากการสอบถามเมื่อคุณตั้งค่าเป็น 0 ดังนั้นแทนที่จะif (value) {}คุณควรใช้if (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends

1
ใน RegExp ([? | &]) ควรเป็น ([? &])
จริงๆ

ตลกที่นำมาจากวิธีการแก้ปัญหาเดิม - ยังสามารถใช้ (\? | &)
ellemayo

1
ได้รับ "ข้อยกเว้นปกติไม่ถูกต้อง / กลุ่มที่ไม่ถูกต้อง" ในการสร้าง regex ใน chrome รุ่น 31.0.1650.63 แก้ไขได้โดยการคืนค่าเริ่มต้นให้เป็น "([? &])"
Yonatan Karni

1
ไม่ว่าเรื่องนี้ยกเว้นสำหรับฉันเป็นโรค แต่ตัวแปรhashถูกประกาศเป็นครั้งที่สอง;)
wlingke

117

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

ตอนนี้คุณไม่จำเป็นต้องเขียน regex หรือตรรกะของคุณเองเพื่อจัดการการมีอยู่ของสตริงการสืบค้น

อย่างไรก็ตามการสนับสนุนเบราว์เซอร์ไม่ดีเนื่องจากขณะนี้อยู่ระหว่างการทดลองและมีการใช้งานเฉพาะใน Chrome, Firefox, Safari, iOS Safari รุ่นล่าสุด, เบราว์เซอร์ Android, Android Chrome และ Opera ใช้ร่วมกับpolyfillหากคุณตัดสินใจที่จะใช้

อัปเดต:การสนับสนุนเบราว์เซอร์ได้รับการปรับปรุงตั้งแต่คำตอบเดิมของฉัน


เติมUnable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference พอลลี่ไม่ดี ใน ie11 คุณได้รับข้อผิดพลาดนั้น มันไม่ได้เป็น pollyfill ถ้ามันไม่ทำงานเป็นทางเลือก
วาล

6
อัปเดต2019 : การสนับสนุนเบราว์เซอร์ตอนนี้ดีสำหรับเบราว์เซอร์ส่วนใหญ่ยกเว้น IE และเบราว์เซอร์มือถือขนาดเล็ก pollyfill ใหม่ของ ungap ครอบคลุมได้อย่างง่ายดาย: github.com/ungap/url-search-params
Flion

คำตอบที่สมบูรณ์แบบ แต่มันไม่ได้จัดการ usecase เมื่อ hashtag มีอยู่ใน 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;
  }
}

แก้ไขเพื่อแก้ไข[?|&]ใน regex ซึ่งแน่นอนควรจะ[?&]เป็นชี้ให้เห็นในความคิดเห็น

แก้ไข: เวอร์ชันทางเลือกเพื่อรองรับการลบพารามิเตอร์ 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 สำหรับผู้ใช้ ui-router เชิงมุมที่สามารถมี "?" ในแฮชเช่นกัน การย้าย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 ทำเช่นนี้

คุณจะต้องการปุ่มย้อนกลับเพื่อใช้งานคุณจะต้องผูกเหตุการณ์จาวาสคริปต์กับกิจกรรมแฮชเปลี่ยนซึ่งเป็นปลั๊กอินที่ดีสำหรับhttp://benalman.com/projects/jquery-hashchange-plugin/


4
Twitter ไม่แก้ไขแฮชอีกต่อไป! แฮชตายแล้วยินดีต้อนรับHistory API !
Alba Mendez

มันไกลจากความตาย ฉันคิดว่าคุณกำลังใช้ชีวิตอยู่ในโลกแห่งเวทมนตร์ที่ซึ่งความเข้ากันได้ของเบราว์เซอร์รุ่นเก่านั้นไม่ต้องกังวล นี่อาจเป็นกรณีของคุณ แต่ก็ไม่ใช่กรณีสำหรับพวกเราที่เหลือ (หรืออันที่จริงแล้วพวกเราส่วนใหญ่) บางทีอาจจะตายจะเหมาะสมกว่า ...
AaronHS

1
หนึ่งปีต่อมาดูเหมือนว่าเบราว์เซอร์กึ่งเดียวที่ไม่รองรับ IE 9
Douglas.Sesar

11

หากยังไม่ได้ตั้งค่าหรือต้องการอัปเดตด้วยค่าใหม่คุณสามารถใช้:

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

นี่คือ Javascript อย่างง่ายโดยวิธีการ

แก้ไข

คุณอาจต้องการลองใช้ปลั๊กอินข้อความค้นหา jquery

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


1
สิ่งนี้จะไม่รักษาพารามิเตอร์สตริงข้อความค้นหาอื่น ๆ บน url แม้ว่า
มือสมัครเล่น

คุณพูดถูกฉันขอโทษ .. เป็นการอัปเดตฉันได้เพิ่มตัวเลือกอื่นให้กับคำตอบของฉัน :)
tradyblix

สิ่งนี้ไม่ทำงานเนื่องจากไม่ได้รีเซ็ตค่า "เพิ่มหรืออัปเดต"
เปาโล 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
นี่เป็นกรณีทดสอบที่ดีและดี + ใช้ DOM เป็นตัวแยกวิเคราะห์ URL ฉันพบสองกรณีแล้ว: example.com/?param=val& => example.com/?param=val&&new=key --double & และexample.com/team => example.com/team?new=key ที่คาดไว้: team /? new = key การเปลี่ยนเส้นทางบางอย่าง / ทีม? new = key ไปยัง / team / และการค้นหาจะหายไป
Timar Ivo Batis

1
ขอบคุณสำหรับกรณีทดสอบที่ล้มเหลว ฉันอัพเดทซอ อันแรกนั้นยาก ความคิดเห็นเกี่ยวกับวิธีการแก้ไขฟังก์ชั่นสำหรับมัน? ครั้งที่สองควรได้รับการจัดการอย่างไม่มีปัญหาและครอบคลุมในชุดทดสอบแล้ว บางทีฉันอาจไม่เข้าใจคุณ อย่าลังเลที่จะแยกซอทดสอบเพื่อแสดงให้เห็นสิ่งที่คุณเห็น
Dominic P

ฉันเพิ่มกรณีทดสอบที่ฉันพบและวิธีแก้ปัญหา ฉันพยายามใช้ DOM ให้มากที่สุด ในขั้นต้นฉันต้องการสิ่งนี้เพื่อใช้งานกับลิงก์ที่เกี่ยวข้องภายในโดเมนเดียวกัน jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis

1
@braed ฉันชอบวิธีการนี้เพราะทำให้การยกเบราว์เซอร์หนักขึ้น ดังที่คุณเห็นจากคำตอบมากมายที่นี่ปัญหานี้ไม่ง่ายอย่างที่คิด มีมุมจำนวนมากที่โซลูชันจำเป็นต้องครอบคลุม ส่วนใหญ่ครอบคลุมฟรีเมื่อคุณใช้ประโยชน์จาก DOM
โดมินิค P

1
@braed แน่ใจว่าเพียงแค่ดูที่ชุดทดสอบที่ฉันเชื่อมโยงในคำตอบ โซลูชันจำนวนมากที่นี่ซึ่งไม่พึ่งพา DOM ล้มเหลวเนื่องจากไม่ได้คำนึงถึงกรณีขอบทั้งหมดที่ระบุไว้ สำหรับการอ่านอาจแนะนำให้ดูโมดูล URLสำหรับ node.js มันไม่ได้เกี่ยวข้องโดยตรง แต่ให้ความคิดเกี่ยวกับความซับซ้อนบางอย่างที่เกี่ยวข้องกับสตริง URL
โดมินิค P

9

นี่คือแนวทางของฉัน: location.params()ฟังก์ชั่น (แสดงด้านล่าง) สามารถใช้เป็นทะเยอทะยานหรือ 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?");
}

ยังล้มเหลวทดสอบเล็กน้อยโดย 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หมายถึงสิ่งเดียวกันและมีความกระชับมากขึ้น
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);
}

regexคำอธิบายสามารถพบได้ที่นี่

หมายเหตุ : โซลูชันนี้ใช้คำตอบ @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

วิธีการที่แตกต่างกันโดยไม่ต้องใช้การแสดงผลปกติ รองรับ 'hash' anchors ที่ส่วนท้ายของ url รวมถึง charcters เครื่องหมายคำถามหลายตัว (?) ควรเร็วกว่าวิธีแสดงออกปกติเล็กน้อย

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

ยินดีต้อนรับคำวิจารณ์ก็โอเค (นี่คือการปรุงอาหารทุกคืนดังนั้นอย่าลังเลที่จะทราบการปรับเปลี่ยน) หากสิ่งนี้ช่วยได้เลยยกนิ้วขึ้นรหัส Happy

ไม่มีการทำซ้ำแต่ละคำขอไม่ซ้ำกันตามที่คุณแก้ไขและเนื่องจากวิธีการนี้มีโครงสร้างและง่ายต่อการเพิ่มแบบสอบถามเพิ่มเติม dynamicaly จากภายใน dom


0

นี่เป็นวิธีทางเลือกโดยใช้คุณสมบัติ inbuilt ขององค์ประกอบ HTML anchor:

  • จัดการพารามิเตอร์ที่มีหลายค่า
  • ไม่มีความเสี่ยงในการแก้ไข # แฟรกเมนต์หรือสิ่งอื่นใดนอกจากสตริงเคียวรีเอง
  • อาจจะอ่านง่ายขึ้นนิดหน่อย? แต่มันก็นานกว่า

    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's

หาก jslint ให้ข้อผิดพลาดให้คุณเพิ่มสิ่งนี้หลังจาก for for loop

if(params.hasOwnProperty(key))

ไม่จัดการแฮชหรือพารามิเตอร์ไม่ได้กำหนดค่า ( http://abc.def/?a&b&c)
Adam Leggett

0

มีคำตอบที่น่าอึดอัดใจและซับซ้อนมากในหน้านี้ อันดับสูงสุดอันดับหนึ่งคือ @ amateur's ค่อนข้างดีถึงแม้จะมีความผิดปกติเล็กน้อยใน RegExp นี่คือทางออกที่ดีที่สุดเล็กน้อยกับ Cleaner 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

separatorupdateQueryStringParamsNoHashไม่ได้กำหนดใน ใน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.