Node.js GET/POST-запросы

Во многих сценариях нашему серверу необходимо взаимодействовать с браузером пользователя, например при отправке формы.

Для отправки форм на сервер обычно используются GET/POST-запросы.

В этой главе мы рассмотрим GET/POST-запросы Node.js.


Получение содержимого GET-запроса

Поскольку GET-запросы напрямую встроены в путь, URL — это полный путь запроса, включая?часть после `?`, поэтому вы можете вручную разобрать содержимое после него как параметры GET-запроса.

В node.js можно использовать конструктор URL для разбора URL запроса.

Объект URL — это стандартный инструмент в Node.js для разбора и обработки URL-адресов. Он предоставляет удобный интерфейс для доступа к различным компонентам URL и их изменения, таким как протокол, имя хоста, путь, параметры запроса и т. д.

Пример

const http = require('http'); const util = require('util'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); //Используйте конструктор URL для разбора URL запроса const myUrl = new URL(req.url, `http://${req.headers.host}`); //Выведите различные части URL res.end(util.inspect({ href: myUrl.href, origin: myUrl.origin, protocol: myUrl.protocol, host: myUrl.host, hostname: myUrl.hostname, port: myUrl.port, pathname: myUrl.pathname, search: myUrl.search, searchParams: Object.fromEntries(myUrl.searchParams) //Преобразуйте searchParams в обычный объект })); }).listen(3000); console.log("Сервер запущен по адресу http://localhost:3000");

Откройте в браузереhttp://localhost:3000/user?name=Example&url=www.example.comЗатем просмотрите возвращённый результат:

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

Мы можем использовать метод url.parse для разбора параметров в URL. Код выглядит так:

Пример

const http = require('http'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); //Используйте конструктор URL для разбора URL запроса const myUrl = new URL(req.url, `http://${req.headers.host}`); //Получение параметров запроса const name = myUrl.searchParams.get("name"); const siteUrl = myUrl.searchParams.get("url"); res.write("Название сайта:" + (name || "Не указано")); res.write("\n"); res.write("URL сайта:" + (siteUrl || "Не указано")); res.end(); }).listen(3000); console.log("Сервер запущен по адресу http://localhost:3000");

Откройте в браузереhttp://localhost:3000/user?name=Example&url=www.example.comЗатем просмотрите возвращённый результат:

Объект URL

Ниже перечислены свойства и методы объекта URL:

Свойство/МетодОписаниеПример вывода
hrefПолная строка URL"http://example.com:8080/path?foo=bar#section"
originИсточник URL, включая протокол, имя хоста и номер порта (если присутствует)"http://example.com:8080"
protocolЧасть URL, содержащая протокол, за которой следует:"http:"
hostимя хоста и номер порта"example.com:8080"
hostnameИмя хоста, исключая номер порта"example.com"
portНомер порта (если указан)"8080"
pathnameЧасть пути"/path"
searchЧасть строки запроса, включая ведущий?"?foo=bar&hello=world"
searchParamsURLSearchParamsОбъект для управления параметрами запроса{ foo: 'bar', hello: 'world' }
hashЧасть якоря, включая#"#section"
МетодОписаниеПример кодаПример вывода
get(name)Получить значение параметра запроса с указанным именемmyUrl.searchParams.get("foo")"bar"
append(name, value)Добавить новый параметр в строку запросаmyUrl.searchParams.append("newKey", "newValue")?foo=bar&newKey=newValue
set(name, value)Установить параметр с указанным именем в строке запроса (обновить, если он уже существует)myUrl.searchParams.set("foo", "newBar")?foo=newBar
delete(name)Удалить параметр запроса с указанным именемmyUrl.searchParams.delete("foo")?hello=world
has(name)Определяет, существует ли параметр с указанным именем в строке запросаmyUrl.searchParams.has("foo")trueилиfalse
forEach(callback)Перебирает пары ключ-значение параметров запроса и выполняет функцию обратного вызоваmyUrl.searchParams.forEach((v, k) => console.log(k, v))Вывод пар ключ-значение
toString()Преобразует параметры запроса в строковую форму, подходящую для перестроения URLmyUrl.searchParams.toString()"foo=bar&hello=world"

Пример

const myUrl = new URL("http://example.com/path?foo=bar&hello=world");

console.log(myUrl.pathname);            // Вывод: /path
console.log(myUrl.searchParams.get("foo")); // Вывод: bar

myUrl.searchParams.append("newKey", "newValue");
console.log(myUrl.href);               // Вывод: http://example.com/path?foo=bar&hello=world&newKey=newValue

Получение содержимого POST-запроса

В Node.js обработка POST-запросов обычно требует получения данных из тела запроса через модуль http. В отличие от GET-запросов, данные POST-запроса не включаются в URL, а передаются как тело запроса. Поэтому при получении POST-данных в Node.js необходимо прослушивать и обрабатыватьrequestобъекта requestdataиendсобытие.

  • Прослушивайтеdataсобытие: когда фрагмент данных поступает на сервер,dataСобытие срабатывает, и фрагмент данных передаётся в колбэк в качестве параметра.
  • Прослушивайтеendсобытие: когда всё тело запроса получено,endСобытие срабатывает, и на этом этапе вы можете обработать полные POST-данные.
Следующий код демонстрирует, как использовать модуль http в Node.js для обработки POST-запросов:

Пример

const http = require('http');

// Создать HTTP-сервер
http.createServer((req, res) => {
    // Проверить, является ли метод запроса POST
    if (req.method === 'POST') {
        let body = '';

        // Прослушивать событие data, получать данные частями
        req.on('data', (chunk) => {
            body += chunk; // Накапливать полученные фрагменты данных
        });

        // Прослушивать событие end, приём данных завершён
        req.on('end', () => {
            // Вывести полученные POST-данные
            console.log('Полученные POST-данные:', body);

            // Установить заголовки и содержимое ответа
            res.writeHead(200, { 'Content-Type': 'text/plain' });
            res.end('POST-данные успешно получены!');
        });

    } else {
        // Обработка не-POST запросов
        res.writeHead(405, { 'Content-Type': 'text/plain' });
        res.end('Поддерживаются только POST-запросы.');
    }

}).listen(3000, () => {
    console.log('Сервер запущен по адресу http://localhost:3000');
});

Пояснение к коду:

  1. Определение метода запроса: Используйтеreq.method === 'POST'чтобы определить, является ли тип запроса POST.
  2. Получение данных: Вreq.on('data')событии, накапливайте фрагменты данных, чтобы сформировать полное тело данных.
  3. Завершение получения: Вreq.on('end')событии, обработайте полные POST-данные.
  4. Ответ клиенту: После завершения приёма и обработки данных отправьте ответ клиенту.

Вы можете использовать команду curl для тестирования POST-запросов:

curl -X POST -d "name=example&age=25" http://localhost:3000

Обработка JSON-данных

Если POST-запрос отправляет данные JSON, вы можетеreq.on('end')разобрать полученные данные в объект:

req.on('end', () => {
    const parsedData = JSON.parse(body); // 将 JSON 字符串解析为对象
    console.log('Received JSON data:', parsedData);
    res.end('JSON data received successfully!');
});

Модуль querystring

Модуль querystring используется для обработки строк запроса URL и данных POST-запросов.

Для данных POST-запроса, закодированных как application/x-www-form-urlencoded, модуль querystring может помочь разобрать тело запроса и преобразовать его в объект JavaScript для удобного доступа и манипулирования.

Предположим, данные POST-запроса, отправленные клиентом, имеют форматapplication/x-www-form-urlencoded(например, отправка формы), и данные похожи наname=example&age=25После получения данных вы можете использоватьquerystring.parseметод для разбора данных в объект.

Объяснение базовой структуры синтаксиса

var http = require('http'); var querystring = require('querystring'); var util = require('util'); http.createServer(function(req, res){ //Определите переменную post для временного хранения информации о теле запроса. var post = ''; //Через функцию-обработчик события data у req, всякий раз при получении данных тела запроса они накапливаются в переменной post. req.on('data', function(chunk){ post += chunk; }); //После срабатывания события end используйте querystring.parse, чтобы разобрать post в фактический формат POST-запроса, а затем вернуть его клиенту. req.on('end', function(){ post = querystring.parse(post); res.end(util.inspect(post)); }); }).listen(3000);

Следующая форма из примера отправляется методом POST и выводит данные:

Пример

var http = require('http'); var querystring = require('querystring'); var postHTML = '<html><head><meta charset="utf-8"><title>Пример руководства Node.js</title></head>' + '<body>' + '<form method="post">' + 'Название сайта: <input name="name"><br>' + 'URL сайта: <input name="url"><br>' + '<input type="submit">' + '</form>' + '</body></html>'; http.createServer(function (req, res) { var body = ""; req.on('data', function (chunk) { body += chunk; }); req.on('end', function () { //Разбор параметров body = querystring.parse(body); //Установка информации заголовка ответа и кодировки res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'}); if(body.name && body.url) { //Вывод отправленных данных res.write("Название сайта:" + body.name); res.write("<br>"); res.write("URL сайта:" + body.url); } else { //Вывод формы res.write(postHTML); } res.end(); }); }).listen(3000);

GIF-демонстрация результата выполнения:

Другие расширения