zkrvndm
@zkrvndm
Архитектор решений

Как преобразовать JavaScript-объект в строку формата application/x-www-form-urlencoded?

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

Раньше для отправки запросов использовал jQuery, а он сам сериализует отсылаемые объекты, но вот решил в очередном проекте везде запихать fetch() и возникла такая проблема) Если у кого-нибудь есть готовое решение, скиньте пожалуйста.
  • Вопрос задан
  • 604 просмотра
Решения вопроса 1
zkrvndm
@zkrvndm Автор вопроса
Архитектор решений
Нашел в сети упоминание, что у конструктора new URLSearchParams() имеются встроенные методы для получения строки запроса, то есть мы можем используя чисто нативные методы сформировать тело запроса:
var objeto = { 'raz' : 'Первое свойство', 'dva' : 'Второе свойство' };

var params = new URLSearchParams();

for (var prop in objeto) {
	params.append(prop, objeto[prop]);
}

console.log(params.toString());

Способ хорош, но он не позволяет преобразовывать вложенные объекты, в этом его минус.

Используя этот метод за основу написал рекурсивный конвертер, который может преобразовывать в строку запроса объекты любого уровня вложенности сколь бы сложные они не были:
// Функция для преобразования объекта
// в строку формата x-www-form-urlencoded:

function httpBuildQuery(object_to_convert) {
	
	var params = new URLSearchParams();
	
	var paramsGenerator = function(parent_key, iterate_object) {
		
		for (var current_key in iterate_object) {
			
			if (typeof iterate_object[current_key] == 'string' || typeof iterate_object[current_key] == 'number') {
				
				if (parent_key.length > 0) {
					var property_path = parent_key + '[' + current_key + ']';
				} else {
					var property_path = current_key;
				}
				
				params.append(property_path, iterate_object[current_key]);
				
			} else if (typeof iterate_object[current_key] == 'object') {
				
				if (parent_key.length > 0) {
					var property_path = parent_key + '[' + current_key + ']';
				} else {
					var property_path = current_key;
				}
				
				paramsGenerator(property_path, iterate_object[current_key]);
				
			}
			
		}
		
	}
	
	paramsGenerator('', object_to_convert);
	
	return params.toString();
	
}

// Потестируем работу функции на примере:

var test_object = {
	'raz' : 'Первое свойство',
	'dva' : 'Второе свойство',
	'tri' : {
		'test' : 'Тест',
		'proverka' : 'Проверка',
		'massiv' : [
			'aaa',
			'bbb',
			'ccc',
			{
				'lalala' : 'lololo',
				'tratata' : 'trototo'
			},
			123,
			345,
			567
		]
	}
};

var send_string = httpBuildQuery(test_object);

var response = await (await fetch('https://nadim.work/post_view.php', {
	method: 'POST',
	headers: {
		'Content-Length' : send_string.length,
		'Content-Type' : 'application/x-www-form-urlencoded'
	},
	body: send_string
})).text();

console.log(response);

Если забьете этот код в консоль увидите, что функция прекрасно справляется с преобразованием. Оставляю код для будущих поколений, надеюсь он еще много кому пригодится, особенно если вам нужно отправить типовой POST-запрос именно через fetch() не используя конструктор new FormData() совсем.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
WblCHA
@WblCHA
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы