Создание строки запроса из объекта в JavaScript
Доброго времени суток! При создании веб-сайтов часто, если не всегда, приходится иметь дело с фильтрацией и сортировкой результатов запроса к базе данных. Эти операции осуществляются на основе данных пришедших в запросе на сервер из браузера, например.
А данные для фильтрации, это как правило, некоторый объект JavaScript, который описывает, какие данные нужны и как их сортировать.
Далле мы рассмотрим с Вами пример, того как можно преобразовать JavaScript объект в строку запроса (query string), которую потом можно будет передать на сервер в виде GET параметра.
Итак, для начала определим некоторые вспомогательные функции, необходимые для работы функции buildQueryString.
// Функция для проверки, является ли объект пустым
function isEmpty(obj) {
// Проверяем, если длина массива ключей объекта равна 0, то объект пуст
if (Object.keys(obj).length === 0) {
return true;
}
// Проверяем каждое свойство объекта на пустоту
for (const key in obj) {
const value = obj[key];
// Если значение не является пустым, объект не пуст
if (
value !== null &&
value !== '' &&
!(Array.isArray(value) && value.length === 0) &&
!(typeof value === 'object' && isEmpty(value))
) {
return false;
}
}
// Если не найдены непустые свойства, объект пуст
return true;
}
// Функция для удаления пустых полей из объекта
function removeEmptyFields(obj) {
return Object.keys(obj).reduce((acc, key) => {
const value = obj[key];
// Если значение не пусто, добавляем его в аккумулятор
if (value !== null && value !== '' && !(Array.isArray(value) && value.length === 0)) {
acc[key] = value;
}
return acc;
}, {});
}
// Функция для построения строки запроса из объекта параметров
function buildQueryString(params = {}, parentKey = null) {
const queryString = [];
// Проверяем, если объект параметров пуст, возвращаем undefined
if (isEmpty(params)) return;
// Обходим каждое свойство объекта параметров
for (const key in params) {
if (params.hasOwnProperty(key)) {
const value = params[key];
// Строим ключ с учетом вложенности
const constructedKey = parentKey ? `${parentKey}[${key}]` : key;
// Если значение является объектом и не пусто, обрабатываем его
if (typeof value === 'object' && Object.entries(value).length !== 0) {
// Удаляем пустые поля из объекта и рекурсивно строим строку запроса для вложенных объектов
const _value = removeEmptyFields(value);
queryString.push(buildQueryString(_value, constructedKey));
} else {
// Если значение существует, добавляем его в строку запроса с кодированием URI
if (value) {
queryString.push(`${constructedKey}=${encodeURIComponent(value)}`);
}
}
}
}
// Фильтруем undefined элементы и пустые строки, объединяем элементы в строку запроса с символом &
return queryString.filter(v => v !== undefined).filter(s => s?.trim().length !== 0).join('&');
}
Тестируем на следующих данных:
const testData =
{
"filters": {
"customer_id": null,
"couriers": [],
"order_statuses": [
6,
5,
3,
1,
7,
8,
4
],
"addresses_from": [],
"addresses_to": [],
"start_datetime": "",
"end_datetime": "",
"customer_cities": [
1,
2,
8
]
},
"sort": {
"customer": "asc"
}
}
const query_string = buildQueryString(testData);
// Получем следующую строку, которую можно отправлять на сервер
// filters[order_statuses][0]=6&filters[order_statuses][1]=5&filters[order_statuses][2]=3&filters[order_statuses][3]=1&filters[order_statuses][4]=7&filters[order_statuses][5]=8&filters[order_statuses][6]=4&filters[customer_cities][0]=1&filters[customer_cities][1]=2&filters[customer_cities][2]=8&sort[customer]=asc
const url = 'https://srs.myruakov.ru' + '?' + query_string;
console.log(url);
Таким образом, объект, который мы передаем в функция buildQueryString может состоять из необходимых для фильтрации и сортировки параметров. Однако, имейте ввиду, что не стоит делать строку запроса (query_string) слишком длинной (можно сделать имена свойств короче в объекте testData), а также, все данные, пришедшие на сервер необходимо обязательно проверять, на соответствие правилам безопасности.