كيف يمكنني الحصول على قيم سلسلة الاستعلام في JavaScript؟

سئل على ٢٣ مايو ٢٠٠٩  ·  تمت مشاهدة 4M مرة  ·  مصدر

Subliminal Hash picture
في ٢٣ مايو ٢٠٠٩

هل هناك طريقة بدون مكون إضافي لاسترداد قيم سلسلة الاستعلام عبر jQuery (أو بدونها)؟

إذا كان الأمر كذلك ، فكيف؟ إذا لم يكن كذلك ، فهل هناك مكون إضافي يمكنه فعل ذلك؟

الإجابات

Artem Barger picture
في ٢٣ مايو ٢٠٠٩
8624

التحديث: سبتمبر 2018

يمكنك استخدام URLSearchParams وهو بسيط ولديه دعم متصفح لائق (ولكن غير كامل) .

const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');

ملاحظة

لسوء الحظ ، لا يقوم URLSearchParams بتحليل سلاسل الاستعلام بشكل صحيح مع قيم ذات مفاتيح سلسلة. قد ترغب في تجربة locutus / parse_str

console.log(new URLSearchParams('a=b&c=d').toString()); // a=b&c=d
console.log(new URLSearchParams('a=b&c=d').get('a')); // b
console.log(new URLSearchParams('filters[a]=b&filters[c]=d').toString()); // filters%5Ba%5D=b&filters%5Bc%5D=d
console.log(new URLSearchParams('filters[a]=b&filters[c]=d').get('filters')); // null

أصلي

لا تحتاج إلى jQuery لهذا الغرض. يمكنك استخدام بعض JavaScript فقط:

function getParameterByName(name, url = window.location.href) {
    name = name.replace(/[\[\]]/g, '\\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

استعمال:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)

ملاحظة: إذا كانت المعلمة موجودة عدة مرات (`؟ foo = lorem & foo؛ = ipsum`) ، فستحصل على القيمة الأولى (` lorem`). لا يوجد معيار حول هذا وتختلف الاستخدامات ، راجع على سبيل المثال هذا السؤال: [الموضع المعتمد لمفاتيح استعلام HTTP GET المكررة] (https://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get -مفاتيح الاستعلام). ملاحظة: الوظيفة حساسة لحالة الأحرف. إذا كنت تفضل اسم معلمة غير حساسة لحالة الأحرف ، [أضف معدّل 'i' إلى RegExp] [2]

هذا تحديث يعتمد على مواصفات URLSearchParams الجديدة لتحقيق نفس النتيجة بإيجاز أكبر. انظر الإجابة بعنوان " URLSearchParams " أدناه.

Andy E picture
في ٢١ مايو ٢٠١٠
1730

بعض الحلول المنشورة هنا غير فعالة. يعد تكرار البحث عن التعبير العادي في كل مرة يحتاج فيها البرنامج النصي للوصول إلى معلمة أمرًا غير ضروري تمامًا ، تكفي وظيفة واحدة لتقسيم المعلمات إلى كائن نمط مصفوفة ترابطية. إذا كنت لا تعمل مع HTML 5 History API ، فهذا ضروري مرة واحدة فقط لكل تحميل صفحة. تفشل الاقتراحات الأخرى هنا أيضًا في فك تشفير عنوان URL بشكل صحيح.

var urlParams;
(window.<a i="6">onpopstate</a> = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return <a i="7">decodeURIComponent</a>(s.replace(pl, " ")); },
        query  = window.<a i="8">location</a>.search.<a i="9">substring</a>(1);

    urlParams = {};
    while (match = search.<a i="10">exec</a>(query))
       urlParams[decode(match[1])] = decode(match[2]);
})();

مثال على سلسلة الاستعلام:

?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty

نتيجة:

 urlParams = {
    enc: " Hello ",
    i: "main",
    mode: "front",
    sid: "de8d49b78a85a322c4155015fdce22c4",
    empty: ""
}

alert(urlParams["mode"]);
// -> "front"

alert("empty" in urlParams);
// -> true

يمكن تحسين هذا بسهولة للتعامل مع سلاسل الاستعلام بنمط المصفوفة أيضًا. يوجد مثال على ذلك هنا ، ولكن نظرًا لأن معلمات نمط الصفيف غير محددة في RFC 3986 ، فلن ألوث هذه الإجابة بشفرة المصدر. للمهتمين بنسخة "ملوثة" ، انظر إلى إجابة campbeln أدناه .

أيضًا ، كما هو موضح في التعليقات ، ; هو محدد قانوني لأزواج key=value . قد يتطلب الأمر استخدام regex أكثر تعقيدًا للتعامل مع ; أو & ، وهو ما أعتقد أنه غير ضروري لأنه نادرًا ما يتم استخدام ; وقد أقول أنه من غير المحتمل أن يكون كلاهما يستخدم. إذا كنت بحاجة إلى دعم ; بدلاً من & ، فما عليك سوى تبديلها في regex.


إذا كنت تستخدم لغة معالجة مسبقة من جانب الخادم ، فقد ترغب في استخدام وظائف JSON الأصلية الخاصة بها للقيام بالأعباء الثقيلة نيابة عنك. على سبيل المثال ، في PHP يمكنك كتابة:
<script>var urlParams = <?php echo <a i="34">json_encode</a>($_GET, JSON_HEX_TAG);?>;</script>

اكثر سهولة!

محدث

هناك إمكانية جديدة تتمثل في استرداد المعلمات المتكررة على النحو التالي myparam=1&myparam=2 . لا توجد مواصفات ، ومع ذلك ، تتبع معظم الأساليب الحالية إنشاء مصفوفة.

myparam = ["1", "2"]

إذن ، هذا هو أسلوب إدارته:

let urlParams = {};
(window.onpopstate = function () {
    let match,
        pl = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
            return decodeURIComponent(s.replace(pl, " "));
        },
        query = window.location.search.substring(1);

    while (match = search.exec(query)) {
        if (decode(match[1]) in urlParams) {
            if (!Array.isArray(urlParams[decode(match[1])])) {
                urlParams[decode(match[1])] = [urlParams[decode(match[1])]];
            }
            urlParams[decode(match[1])].push(decode(match[2]));
        } else {
            urlParams[decode(match[1])] = decode(match[2]);
        }
    }
})();
BrunoLM picture
في ٤ أكتوبر ٢٠١٠
1296

ES2015 (ES6)

getQueryStringParams = query => {
    return query
        ? (/^[?#]/.test(query) ? query.slice(1) : query)
            .split('&')
            .reduce((params, param) => {
                    let [key, value] = param.split('=');
                    params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
                    return params;
                }, {}
            )
        : {}
};

بدون مسج

var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
        var p=a[i].split('=', 2);
        if (p.length == 1)
            b[p[0]] = "";
        else
            b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return b;
})(window.location.search.substr(1).split('&'));

باستخدام عنوان URL مثل ?topic=123&name=query+string ، سيتم عرض ما يلي:

qs["topic"];    // 123
qs["name"];     // query string
qs["nothere"];  // undefined (object)

طريقة جوجل

تمزيق رمز Google وجدت الطريقة التي يستخدمونها: getUrlParameters

function (b) {
    var c = typeof b === "undefined";
    if (a !== h && c) return a;
    for (var d = {}, b = b || k[B][vb], e = b[p]("?"), f = b[p]("#"), b = (f === -1 ? b[Ya](e + 1) : [b[Ya](e + 1, f - e - 1), "&", b[Ya](f + 1)][K](""))[z]("&"), e = i.dd ? ia : unescape, f = 0, g = b[w]; f < g; ++f) {
        var l = b[f][p]("=");
        if (l !== -1) {
            var q = b[f][I](0, l),
                l = b[f][I](l + 1),
                l = l[Ca](/\+/g, " ");
            try {
                d[q] = e(l)
            } catch (A) {}
        }
    }
    c && (a = d);
    return d
}

إنه غامض ، لكنه مفهوم. لا يعمل لأن بعض المتغيرات غير معرفة.

يبدأون في البحث عن المعلمات على عنوان url من ? وأيضًا من التجزئة # . ثم لكل معلمة يتم تقسيمهم في علامة التساوي b[f][p]("=") (والتي تبدو مثل indexOf ، يستخدمون موضع الحرف للحصول على المفتاح / القيمة). بعد تقسيمها ، يتحققون مما إذا كانت المعلمة لها قيمة أم لا ، وإذا كانت كذلك ، فإنهم يقومون بتخزين قيمة d ، وإلا فسيستمرون.

في النهاية ، تم إرجاع الكائن d ، مع معالجة علامة الهروب وعلامة + . هذا الكائن يشبهني تمامًا ، له نفس السلوك.


طريقتي كمكوِّن إضافي لـ jQuery

(function($) {
    $.QueryString = (function(paramsArray) {
        let params = {};

        for (let i = 0; i < paramsArray.length; ++i)
        {
            let param = paramsArray[i]
                .split('=', 2);
            
            if (param.length !== 2)
                continue;
            
            params[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
        }
            
        return params;
    })(window.location.search.substr(1).split('&'))
})(jQuery);

إستعمال

//Get a param
$.QueryString.param
//-or-
$.QueryString["param"]
//This outputs something like...
//"val"

//Get all params as object
$.QueryString
//This outputs something like...
//Object { param: "val", param2: "val" }

//Set a param (only in the $.QueryString object, doesn't affect the browser's querystring)
$.QueryString.param = "newvalue"
//This doesn't output anything, it just updates the $.QueryString object

//Convert object into string suitable for url a querystring (Requires jQuery)
$.param($.QueryString)
//This outputs something like...
//"param=newvalue&param2=val"

//Update the url/querystring in the browser's location bar with the $.QueryString object
history.replaceState({}, '', "?" + $.param($.QueryString));
//-or-
history.pushState({}, '', "?" + $.param($.QueryString));

اختبار الأداء (طريقة الانقسام مقابل طريقة regex) ( jsPerf )

كود التحضير: بيان الطرق

كود اختبار الانقسام

var qs = window.GetQueryString(query);

var search = qs["q"];
var value = qs["value"];
var undef = qs["undefinedstring"];

كود اختبار Regex

var search = window.getParameterByName("q");
var value = window.getParameterByName("value");
var undef = window.getParameterByName("undefinedstring");

الاختبار في Firefox 4.0 x86 على Windows Server 2008 R2 / 7 x64

  • طريقة التقسيم : 144،780 ± 2.17٪ أسرع
  • طريقة Regex : 13891 ± 0.85٪ | 90٪ أبطأ
James picture
في ١ مارس ٢٠١١
666

نسخة محسنة من إجابة Artem Barger :

function getParameterByName(name) {
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

لمزيد من المعلومات حول التحسين ، راجع: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/

Paul Sweatte picture
في ٢٨ أغسطس ٢٠١٢
608

URLSearchParams

يدعم Firefox 44+ و Opera 36+ و Edge 17+ و Safari 10.3+ و Chrome 49+ واجهة برمجة تطبيقات

هناك برنامج Google URLSearchParams polyfill الذي اقترحه

لم يتم توحيده من قبل W3C ، ولكنه مستوى معيشة بواسطة WhatWG .

يمكنك استخدامه على location :

let params = new URLSearchParams(location.search);

أو

let params = (new URL(location)).searchParams;

أو بالطبع على أي عنوان URL:

let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search);

يمكنك الحصول على المعلمات أيضًا باستخدام خاصية الاختزال .searchParams على كائن URL ، مثل هذا:

let params = new URL('https://example.com?foo=1&bar=2').searchParams;
params.get('foo'); // "1"
params.get('bar'); // "2" 

يمكنك قراءة / تعيين المعلمات من خلال واجهة برمجة تطبيقات get(KEY) ، set(KEY, VALUE) ، append(KEY, VALUE) API. يمكنك أيضًا التكرار على جميع القيم for (let p of params) {} .

يتوفر تنفيذ مرجعي وعينة صفحة للتدقيق والاختبار.

AlfaTeK picture
في ١٥ مارس ٢٠١١
400

مجرد توصية أخرى. يسمح المكون الإضافي Purl باسترداد جميع أجزاء URL ، بما في ذلك المرساة والمضيف وما إلى ذلك.

يمكن استخدامه مع أو بدون jQuery.

الاستخدام بسيط جدًا ورائع:

var url = $.url('http://allmarkedup.com/folder/dir/index.html?item=value'); // jQuery version
var url = purl('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.attr('protocol'); // returns 'http'
url.attr('path'); // returns '/folder/dir/index.html'

ومع ذلك ، اعتبارًا من 11 نوفمبر 2014 ، لم يعد يتم الاحتفاظ بـ Purl ويوصي المؤلف باستخدام URI مباشرة ، مع أو بدون jQuery. سيبدو الرمز المماثل على هذا النحو ، المستندات الكاملة هنا :

var url = new URI('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.protocol(); // returns 'http'
url.path(); // returns '/folder/dir/index.html'
Qwerty picture
في ١٦ يناير ٢٠١٤
244

TL ؛ د

حل سريع المفاتيح والأحرف المشفرة متعددة القيم .

var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (qd[k] = qd[k] || []).push(v)})

//using ES6   (23 characters cooler)
var qd = {};
if (location.search) location.search.substr(1).split`&`.forEach(item => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v)})
متعدد الخطوط:
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {
    var s = item.split("="),
        k = s[0],
        v = s[1] && decodeURIComponent(s[1]); //  null-coalescing / short-circuit
    //(k in qd) ? qd[k].push(v) : qd[k] = [v]
    (qd[k] = qd[k] || []).push(v) // null-coalescing / short-circuit
})

ما هو كل هذا الرمز ...
"الاندماج الصفري" ، تقييم ماس كهربائىES6 تدمير التعيينات ، وظائف الأسهم ، سلاسل القالب

مثال:
"?a=1&b=0&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

> qd.a[1]    // "5"
> qd["a"][1] // "5"



إقرأ المزيد ... حول حل Vanilla JavaScript.

للوصول إلى أجزاء مختلفة من عنوان URL ، استخدم location.(search|hash)

أسهل حل (وهمي)

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • يتعامل مع المفاتيح الفارغة بشكل صحيح.
  • يتجاوز المفاتيح المتعددة بآخر قيمة تم العثور عليها.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

مفاتيح متعددة القيم

شيك بسيط بمفتاح (item in dict) ? dict.item.push(val) : dict.item = [val]

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {(item.split("=")[0] in qd) ? qd[item.split("=")[0]].push(item.split("=")[1]) : qd[item.split("=")[0]] = [item.split("=")[1]]})
  • الآن إرجاع المصفوفات بدلاً من ذلك.
  • قيم الوصول بمقدار qd.key[index] أو qd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

الحروف المشفرة؟

استخدم decodeURIComponent() للتقسيم الثاني أو كلاهما .

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var k = item.split("=")[0], v = decodeURIComponent(item.split("=")[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
مثال:
"?a=1&b=0&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: ["undefined"]  // decodeURIComponent(undefined) returns "undefined" !!!*
e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]



من التعليقات

* !!! يرجى ملاحظة أن decodeURIComponent(undefined) تُرجع السلسلة "undefined" . يكمن الحل في استخدام بسيط لـ && ، مما يضمن عدم استدعاء decodeURIComponent() على قيم غير محددة. (انظر "الحل الكامل" في الأعلى).

v = v && decodeURIComponent(v);


إذا كانت سلسلة الاستعلام فارغة ( location.search == "" ) ، تكون النتيجة مضللة إلى حد ما qd == {"": undefined} . يُقترح التحقق من سلسلة الاستعلام قبل تشغيل وظيفة الإعراب مثل:

if (location.search) location.search.substr(1).split("&").forEach(...)
brandonjp picture
في ١٩ مارس ٢٠١٠
220

يحتوي Roshambo على snipplr.com على نص بسيط لتحقيق هذا الموضح في Get URL Parameters with jQuery |

ها هي الجوهر:

$.urlParam = function(name, url) {
    if (!url) {
     url = window.location.href;
    }
    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
    if (!results) { 
        return undefined;
    }
    return results[1] || undefined;
}

ثم فقط احصل على المعلمات الخاصة بك من سلسلة الاستعلام.

لذلك إذا كان عنوان URL / سلسلة الاستعلام هي xyz.com/index.html?lang=de .

فقط اتصل بـ var langval = $.urlParam('lang'); ، وستحصل عليه.

يحتوي UZBEKJON على مدونة رائعة حول هذا أيضًا ، احصل على معلمات وقيم عناوين URL باستخدام jQuery .

alex picture
في ٢٣ مايو ٢٠٠٩
166

إذا كنت تستخدم jQuery ، فيمكنك استخدام مكتبة ، مثل jQuery BBQ: Back Button & Query Library .

... يوفر jQuery BBQ طريقة .deparam() ، جنبًا إلى جنب مع كل من إدارة حالة التجزئة ، وطرق تحليل سلسلة الجزء / الاستعلام ودمجها.

تحرير: إضافة ديبارام مثال:

 var DeparamExample = function() {
            var params = $.deparam.querystring();

            //nameofparam is the name of a param from url
            //code below will get param if ajax refresh with hash
            if (typeof params.nameofparam == 'undefined') {
                params = jQuery.deparam.fragment(window.location.href);
            }
            
            if (typeof params.nameofparam != 'undefined') {
                var paramValue = params.nameofparam.toString();
                  
            }
        };

إذا كنت تريد فقط استخدام JavaScript عادي ، فيمكنك استخدام ...

var getParamValue = (function() {
    var params;
    var resetParams = function() {
            var query = window.location.search;
            var regex = /[?&;](.+?)=([^&;]+)/g;
            var match;

            params = {};

            if (query) {
                while (match = regex.exec(query)) {
                    params[match[1]] = decodeURIComponent(match[2]);
                }
            }    
        };

    window.addEventListener
    && window.addEventListener('popstate', resetParams);

    resetParams();

    return function(param) {
        return params.hasOwnProperty(param) ? params[param] : null;
    }

})();​

بسبب واجهة برمجة تطبيقات سجل HTML الجديدة وبالتحديد history.pushState() و history.replaceState() ، يمكن أن يتغير عنوان URL مما يؤدي إلى إبطال ذاكرة التخزين المؤقت للمعلمات وقيمها.

سيقوم هذا الإصدار بتحديث ذاكرة التخزين المؤقت الداخلية الخاصة به للمعلمات في كل مرة يتغير فيها السجل.

Martin Borthiry picture
في ٣ سبتمبر ٢٠١٢
100

مجرد استخدام اثنين من الانشقاقات:

function get(n) {
    var half = location.search.split(n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

كنت أقرأ جميع الإجابات السابقة والأكثر اكتمالاً. لكنني أعتقد أن هذه هي الطريقة الأبسط والأسرع. يمكنك التحقق من هذا المعيار jsPerf

لحل المشكلة في تعليق Rup ، أضف تقسيمًا شرطيًا عن طريق تغيير السطر الأول إلى السطرين أدناه. لكن الدقة المطلقة تعني أنه الآن أبطأ من التعبير العادي (انظر

function get(n) {
    var half = location.search.split('&' + n + '=')[1];
    if (!half) half = location.search.split('?' + n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

لذا إذا كنت تعلم أنك لن تواجه قضية روب المضادة ، فهذا يفوز. خلاف ذلك ، regexp.

أو إذا كنت تتحكم في سلسلة الاستعلام ويمكن أن تضمن أن القيمة التي تحاول الحصول عليها لن تحتوي أبدًا على أي أحرف مشفرة لعنوان URL (سيكون وجود هذه في قيمة فكرة سيئة) - يمكنك استخدام الإصدار التالي الأكثر بساطة وقابلية للقراءة من الخيار الأول:

    function getQueryStringValueByName(name) {
        var queryStringFromStartOfValue = location.search.split(name + '=')[1];
         return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;