Параметры 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 в целом четко не определен , так что вы иногда можете увидеть;
или&
в качестве разделителей . -
Наша функция по-прежнему работает, если параметр не имеет знака равенства или если он имеет знак равенства, но не имеет значения.
-
Значения повторяющихся параметров помещаются в массив.
Если вам просто нужна функция, которую вы можете добавить в свой код, все готово. Если вы хотите понять, как работает эта функция, читайте дальше.
В следующем разделе предполагается, что вы знаете некоторый 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. Независимо от того, используете ли вы свой собственный код или пользуетесь библиотекой, обязательно проверьте все и убедитесь, что он работает для ваших случаев использования.