Статьи

Совет: получите параметры URL с помощью JavaScript

Параметры URL (также называемые параметрами строки запроса или переменными URL) используются для отправки небольших объемов данных со страницы на страницу или с клиента на сервер через URL. Они могут содержать все виды полезной информации, например, поисковые запросы, ссылки на ссылки, информацию о продукте, предпочтения пользователя и многое другое.

В этой статье мы покажем вам, как анализировать и обрабатывать параметры URL с помощью JavaScript.

Эта статья была обновлена ​​в 2020 году для актуальности и точности.

Получение параметра URL

В современных браузерах это стало намного проще благодаря интерфейсу URLSearchParams . Это определяет множество служебных методов для работы со строкой запроса URL.

Предполагая, что наш URL-адрес https://example.com/?product=shirt&color=blue&newuser&size=m , мы можем получить строку запроса, используя window.location.search :

 const queryString = window.location.search; console.log(queryString); // ?product=shirt&color=blue&newuser&size=m 

Затем мы можем проанализировать параметры строки запроса, используя URLSearchParams :

 const urlParams = new URLSearchParams(queryString); 

Затем мы вызываем любой из его методов на результат.

Например, URLSearchParams.get() вернет первое значение, связанное с данным параметром поиска:

 const product = urlParams.get('product') console.log(product); // shirt const color = urlParams.get('color') console.log(color); // blue const newUser = urlParams.get('newuser') console.log(newUser); // empty string 

Другие полезные методы

Проверка на наличие параметра

Вы можете использовать URLSearchParams.has() чтобы проверить, существует ли определенный параметр:

 console.log(urlParams.has('product')); // true console.log(urlParams.has('paymentmethod')); // false 

Получение всех значений параметра

Вы можете использовать URLSearchParams.getAll() чтобы вернуть все значения, связанные с конкретным параметром:

 console.log(urlParams.getAll('size')); // [ 'm' ] //Programmatically add a second size parameter. urlParams.append('size', 'xl'); console.log(urlParams.getAll('size')); // [ 'm', 'xl' ] 

Перебор параметров

URLSearchParams также предоставляет некоторые знакомые методы итератора Object , позволяющие перебирать его ключи, значения и записи:

 const keys = urlParams.keys(), values = urlParams.values(), entries = urlParams.entries(); for (const key of keys) console.log(key); // product, color, newuser, size for (const value of values) console.log(value); // shirt, blue, , m for(const entry of entries) { console.log(`${entry[0]}: ${entry[1]}`); } // product: shirt // color: blue // newuser: // size: m 

Поддержка браузера

Поддержка браузера для URLSearchParams хорошая . На момент написания он поддерживается во всех основных браузерах.

Если вам нужна поддержка устаревших браузеров, таких как Internet Explorer , есть полифилл . Или вы можете следовать этому уроку и научиться делать свои собственные.

Прокручиваем собственную функцию анализа строки запроса

Давайте останемся с URL, который мы использовали в предыдущем разделе:

 http://example.com/?product=shirt&color=blue&newuser&size=m 

Вот функция, чтобы дать вам все параметры URL как аккуратный объект:

 function getAllUrlParams(url) { // get query string from url (optional) or window var queryString = url ? url.split('?')[1] : window.location.search.slice(1); // we'll store the parameters here var obj = {}; // if query string exists if (queryString) { // stuff after # is not part of query string, so get rid of it queryString = queryString.split('#')[0]; // split our query string into its component parts var arr = queryString.split('&'); for (var i = 0; i < arr.length; i++) { // separate the keys and the values var a = arr[i].split('='); // set parameter name and value (use 'true' if empty) var paramName = a[0]; var paramValue = typeof (a[1]) === 'undefined' ? true : a[1]; // (optional) keep case consistent paramName = paramName.toLowerCase(); if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase(); // if the paramName ends with square brackets, eg colors[] or colors[2] if (paramName.match(/\[(\d+)?\]$/)) { // create key if it doesn't exist var key = paramName.replace(/\[(\d+)?\]/, ''); if (!obj[key]) obj[key] = []; // if it's an indexed array eg colors[2] if (paramName.match(/\[\d+\]$/)) { // get the index value and add the entry at the appropriate position var index = /\[(\d+)\]/.exec(paramName)[1]; obj[key][index] = paramValue; } else { // otherwise add the value to the end of the array obj[key].push(paramValue); } } else { // we're dealing with a string if (!obj[paramName]) { // if it doesn't exist, create property obj[paramName] = paramValue; } else if (obj[paramName] && typeof obj[paramName] === 'string'){ // if property does exist and it's a string, convert it to an array obj[paramName] = [obj[paramName]]; obj[paramName].push(paramValue); } else { // otherwise add the property obj[paramName].push(paramValue); } } } } return obj; } 

Вы скоро увидите, как это работает, но сначала приведем несколько примеров использования:

 getAllUrlParams().product; // 'shirt' getAllUrlParams().color; // 'blue' getAllUrlParams().newuser; // true getAllUrlParams().nonexistent; // undefined getAllUrlParams('http://test.com/?a=abc').a; // 'abc' не getAllUrlParams().product; // 'shirt' getAllUrlParams().color; // 'blue' getAllUrlParams().newuser; // true getAllUrlParams().nonexistent; // undefined getAllUrlParams('http://test.com/?a=abc').a; // 'abc' 

А вот демоверсия, с которой вы можете поиграть.

Что нужно знать перед использованием этой функции

  • Наша функция предполагает, что параметры разделены символом & , как указано в спецификациях W3C . Тем не менее, формат параметра URL в целом четко не определен , так что вы иногда можете увидеть ; или &amp; в качестве разделителей .

  • Наша функция по-прежнему работает, если параметр не имеет знака равенства или если он имеет знак равенства, но не имеет значения.

  • Значения повторяющихся параметров помещаются в массив.

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

В следующем разделе предполагается, что вы знаете некоторый JavaScript, включая функции, объекты и массивы. Если вам нужен освежающий напиток, ознакомьтесь со справочником MDN JavaScript

Как работает функция

В целом, функция берет строку запроса URL (часть после ? И перед # ) и выплевывает данные в аккуратный объект.

Во-первых, эта строка говорит, что если мы указали URL-адрес, получите все после знака вопроса, но в противном случае просто используйте URL-адрес окна:

 var queryString = url ? url.split('?')[1] : window.location.search.slice(1); 

Далее мы создадим объект для хранения наших параметров:

 var obj = {}; 

Если строка запроса существует, мы начнем ее анализ. Сначала мы должны убедиться, что выбрили часть, начиная с # , поскольку она не является частью строки запроса:

 queryString = queryString.split('#')[0]; 

Теперь мы можем разбить строку запроса на составные части:

 var arr = queryString.split('&'); 

Это даст нам массив, который выглядит следующим образом:

 ['product=shirt', 'color=blue', 'newuser', 'size=m'] 

Далее мы пройдемся по этому массиву и разделим каждый элемент на ключ и значение, которые вскоре добавим в наш объект:

 var a = arr[i].split('='); 

Давайте назначим ключ и значение отдельным переменным. Если значение параметра отсутствует, мы установим его значение true чтобы указать, что имя параметра существует. Не стесняйтесь изменять это в зависимости от вашего варианта использования:

 var paramName = a[0]; var paramValue = typeof (a[1]) === 'undefined' ? true : a[1]; 

При желании вы можете установить все имена параметров и значения в нижний регистр. Таким образом, вы можете избежать ситуаций, когда кто-то отправляет трафик на URL с example=TRUE вместо example=true и ваш скрипт прерывается. (Я видел, как это происходит.) Однако, если ваша строка запроса должна быть чувствительна к регистру, не стесняйтесь пропустить эту часть:

 paramName = paramName.toLowerCase(); if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase(); 

Далее нам нужно разобраться с различными типами ввода, которые мы можем получить в paramName . Это может быть индексированный массив, неиндексированный массив или обычная строка.

Если это индексированный массив, мы хотим, чтобы соответствующее paramValue было массивом со значением, вставленным в правильную позицию. Если это неиндексированный массив, мы хотим, чтобы соответствующее paramValue было массивом с добавленным в него элементом. Если это строка, мы хотим создать обычное свойство для объекта и назначить ему paramValue , если это свойство уже не существует, и в этом случае мы хотим преобразовать существующее paramValue в массив и paramValue в него входящее paramValue .

Чтобы проиллюстрировать это, вот несколько примеров ввода с ожидаемым результатом:

 getAllUrlParams('http://example.com/?colors[0]=red&colors[2]=green&colors[6]=blue'); // { "colors": [ "red", null, "green", null, null, null, "blue" ] } getAllUrlParams('http://example.com/?colors[]=red&colors[]=green&colors[]=blue'); // { "colors": [ "red", "green", "blue" ] } getAllUrlParams('http://example.com/?colors=red&colors=green&colors=blue'); // { "colors": [ "red", "green", "blue" ] } getAllUrlParams('http://example.com/?product=shirt&color=blue&newuser&size=m'); // { "product": "shirt", "color": "blue", "newuser": true, "size": "m" } 

А вот код для реализации функциональности:

 if (paramName.match(/\[(\d+)?\]$/)) { var key = paramName.replace(/\[(\d+)?\]/, ''); if (!obj[key]) obj[key] = []; if (paramName.match(/\[\d+\]$/)) { var index = /\[(\d+)\]/.exec(paramName)[1]; obj[key][index] = paramValue; } else { obj[key].push(paramValue); } } else { if (!obj[paramName]) { obj[paramName] = paramValue; } else if (obj[paramName] && typeof obj[paramName] === 'string'){ obj[paramName] = [obj[paramName]]; obj[paramName].push(paramValue); } else { obj[paramName].push(paramValue); } } 

Наконец, мы возвращаем наш объект с параметрами и значениями.

Если в вашем URL есть какие-либо закодированные специальные символы, такие как пробелы (закодированные как %20 ), вы также можете декодировать их, чтобы получить исходное значение, например:

 // assume a url parameter of test=a%20space var original = getAllUrlParams().test; // 'a%20space' var decoded = decodeURIComponent(original); // 'a space' 

Просто будьте осторожны, чтобы не декодировать то, что уже декодировано, иначе ваш скрипт выдаст ошибку, особенно если в этом задействован процент.

В любом случае, поздравляю! Теперь вы знаете, как получить параметр URL, и, надеюсь, подобрали некоторые другие приемы.

Вывод

Код в этой статье работает для наиболее распространенных случаев использования, где вы получите параметр запроса URL. Если вы работаете с любыми крайними случаями, такими как необычные разделители или специальное форматирование, то обязательно протестируйте и отрегулируйте соответствующим образом.

Если вы хотите сделать больше с URL-адресами, есть специальные библиотеки, такие как строка запроса и Medialize URI.js. Но поскольку это в основном манипуляции со строками, часто имеет смысл просто использовать простой JavaScript. Независимо от того, используете ли вы свой собственный код или пользуетесь библиотекой, обязательно проверьте все и убедитесь, что он работает для ваших случаев использования.