Все данные запроса передаются через объект request - первый параметр функции обратного вызова Функция, которая передается в функцию http.createServer(). Однако получить из него отправленные клиентом данные может представлять сложность. Прежде всего потому, что функция обратного вызова в http.createServer() вызывается при получении всех HTTP-заголовков, но не тела запроса. Кроме того, сам объект request представляет поток, который получает данные отдельными чанками. Соответственно для получения данных из запроса нам необходимо прослушивать этот поток и последовательно извлекать их него полученные чанки информации.
В этом случае для получения данных мы можем использовать разные способы.
Первый способ представляет прослушивание события data обработчик которого получает пришедшие чанки информации. А когда все данные получены, срабатывает событие end. Например, определим следующий простейший сервер:
const http = require("http"); const fs = require("fs"); http.createServer((request, response) => { if (request.url === "/user") { let data = ""; request.on("data", chunk => { data += chunk; }); request.on("end", () => { console.log(data); response.end("Данные успешно получены"); }); } else{ fs.readFile("index.html", (error, data) => response.end(data)); } }).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
При обращении по адресу "/user" с помощью метода request.on устанавливаем для события data функцию-обработчик. Эта функция в качестве параметра получает очередной пришедший кусочек оправленных данных в виде параметра chunk. В данном случае мы ожидаем, что клиент будет отправлять текст. И в функции-обработчике добавляем полученные данные к переменной data. И каждый раз, когда приложение получит очередную порцию данных, будет срабатывать данные обработчик и добавлять данные к переменной data.
Когда все данные будут получены, сработает событие end, в функции-обработчике которого мы уже будем знать, что все данные получены и мы можем производить с ними необходимые нам манипуляции. В данном случае полученные данные просто выводяться на консоль, а в ответ клиенту отправляется некоторое уведомление.
Для тестирования можно определить следующий клиент - страницу index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> </head> <body> <script> sendUser(); async function sendUser() { const response = await fetch("/user", { method: "POST", body: "Tom Smith"}); const responseText = await response.text(); console.log(responseText); } </script> </body> </html>
Здесь клиент отправляет на сервер некоторую строку, которую сервер после получения выведет на консоль:
Второй способ представляет перебор объекта request, который также предоставляет асинхронный итератор для получаемых данных:
const http = require("http"); const fs = require("fs"); http.createServer(async (request, response) => { if (request.url === "/user") { const buffers = []; // буфер для получаемых данных for await (const chunk of request) { buffers.push(chunk); // добавляем в буфер все полученные данные } const data = Buffer.concat(buffers).toString(); console.log(data); response.end("Данные успешно получены"); } else{ fs.readFile("index.html", (error, data) => response.end(data)); } }).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
Здесь вначале определяем буфер для добавляемых данных:
const buffers = [];
Далее перебираем объект request, получая из него данные и добавляя их в буфер buffers:
for await (const chunk of request) { buffers.push(chunk); }
И в конце с помощью функции Buffer.concat() объединяем все полученные данные и преобразуем их в строку методом toString()
:
const data = Buffer.concat(buffers).toString();
При этом мы неограничены получением только текстовых данных. Например, получим данные в формате json:
const http = require("http"); const fs = require("fs"); http.createServer(async (request, response) => { if (request.url === "/user") { const buffers = []; // буфер для получаемых данных for await (const chunk of request) { buffers.push(chunk); // добавляем в буфер все полученные данные } const user = JSON.parse(Buffer.concat(buffers).toString()); console.log(user.name,"-", user.age); response.end("Данные успешно получены"); } else{ fs.readFile("index.html", (error, data) => response.end(data)); } }).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
Здесь предолагается, что клиент посылает серверу объект в формате JSON, у которого есть свойства name и age. И с помощью функции JSON.parse()
мы можем расарсить полученные данные в формат json.
Код клиента для текстирования мог бы выглядеть следующим образом:
sendUser(); async function sendUser(user) { const response = await fetch("/user", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "Tom", age: 37 }) }); const responseText = await response.text(); console.log(responseText); }
В этом случае вывод сервера будет выглядеть следующим образом: