Создание сервера в Node.js
Для работы с сервером и протоколом http в Node.js используется модуль http, подключаемый с помощью require() или import:
1 2 3 |
const http = require("http"); // или import "http"; |
Чтобы создать сервер (объект <http.Server>), следует вызвать метод http.createServer([options][, requestListener]), где
- options <Object>:
- IncomingMessage <http.IncomingMessage> (по умолчанию IncomingMessage) - задает класс IncomingMessage, который можно использовать для доступа к статусу ответа, заголовкам и данным;
- ServerResponse <http.ServerResponse> - указывает используемый класс ServerResponse, полезно для расширения оригинального ServerResponse (по умолчанию: ServerResponse);
- insecureHTTPParser <boolean> (по умолчанию: false) - если TRUE, то использовать небезопасный анализатор HTTP, который принимает недопустимые заголовки HTTP (следует избегать использования небезопасного парсера);
- maxHeaderSize <number> - опционально переопределяет значение --max-http-header-size для запросов, полученных этим сервером, т.е. максимальную длину заголовков запроса в байтах (по умолчанию: 16384 (16 КБ);
- noDelay <boolean> (по умолчанию: false) - если TRUE, он отключает использование алгоритма Нэгла сразу после получения нового входящего соединения;
- keepAlive <boolean> (по умолчанию: false) - если TRUE, активируется функция поддержания активности на сокете сразу после получения нового входящего соединения, аналогично тому, что делается в [socket.setKeepAlive([enable][, initialDelay])][socket. setKeepAlive (включить, InitialDelay)];
- keepAliveInitialDelay <number> (по умолчанию: 0) - если положительное число, задается начальная задержка перед отправкой первой проверки активности на незанятый сокет.
- requestListener - функция, которая автоматически добавляется к событию request.
Метод response.end([data[, encoding]][, callback]) должен вызываться для каждого ответа: он сообщает серверу, что все заголовки и тело ответа отправлены и сервер должен считать сообщение полным.
Чтобы сервер мог прослушивать и обрабатывать входящие подключения, у объекта сервера необходимо вызвать метод listen(), в который в качестве параметра передается номер порта, по которому запускается сервер, например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import http from "http"; // Создаем локальный сервер для получения данных const server = http.createServer((req, res) => { // установим заголовки res.writeHead(200, { "Content-Type": "application/json" }); // завершим отправку ответа res.end( JSON.stringify({ data: "Hello? World!", }) ); }); server.listen(3000); |
где
- request - параметр, в который передается информация о запросе;
- response - параметр, который управляет отправкой ответа.
Параметр Request
Параметр request позволяет получить информацию о запросе и представляет объект http.IncomingMessage (расширяющий класс stream.Readable), и имеющий такие свойства как:
- headers - заголовки запроса;
- method - тип запроса (GET, POST, DELETE, PUT);
- url - запрошенный адрес.
За счет расширения класса stream.Readable для request доступно, например, событие data (генерируется всякий раз, когда поток передает часть данных -chank) или событие end (генерируется, когда в потоке заканчиваются передаваемые данные).
Например:
1 2 3 4 5 6 7 8 9 |
import http from "http"; const server = http.createServer((req, res) => { console.log(req.url) res.end() ); }); server.listen(3000); |
Если обратиться в браузере по адресу http://localhost:3000/index.html, то в консоли терминала увидим строку "/index.html".
Параметр Response
Параметр response управляет отправкой ответа и представляет объект <http.ServerResponse>. Среди его функциональности можно выделить следующие методы:
- statusCode (number, по умолчанию "200") - устанавливает код ответа (например, 200 или 404);
- statusMessage - устанавливает сообщение, отправляемое вместе со статусным кодом (например, "Not found");
- setHeader(name, value) - добавляет в ответ один заголовок;
- write - пишет в поток ответа (отправляет) часть тела ответа; этот метод может вызываться несколько раз для предоставления последовательных частей тела;
- writeHead - добавляет в ответ статусный код, статусное сообщение и набор заголовков;
- end - должен вызываться для каждого ответа: он сообщает серверу, что все заголовки и тело ответа подготовлены и сервер должен считать сообщение полным.
Например:
1 2 3 4 5 6 7 8 9 10 |
import http from "http"; http .createServer((req, res) => { res.setHeader("UserId", 12); res.setHeader("Content-Type", "text/html; charset=utf-8;"); res.write("<h2>hello world</h2>"); res.end(); }) .listen(3000); |
Отправка ответа в Node.js
Если предстоит отправить довольно большой ответ, то мы можем несколько раз вызвать метод write(), который пишет в поток ответа (отправляет) часть тела ответа, последовательно оправляя в исходящий поток каждый кусочек информации. Например, отправим код веб-страницы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import http from "http"; http.createServer(function(request, response){ response.setHeader("Content-Type", "text/html"); response.write("<!DOCTYPE html>"); response.write("<html>"); response.write("<head>"); response.write("<title>Hello USER</title>"); response.write("<meta charset=\"utf-8\" />"); response.write("</head>"); response.write("<body><h1>Hello, user!</h1></body>"); response.write("<button>Click!</button>"); response.write("</html>"); response.end(); }).listen(3000); |
Маршрутизация в Node.js
По умолчанию Node.js не имеет встроенной системы маршрутизации, поэтому обычно она реализуется с помощью специальных фреймворков (например, Express). Однако если необходимо разграничить простейшую обработку пары-тройки маршрутов, то вполне можно использовать для этого свойство url объекта Request. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import http from "http"; http .createServer(function (req, res) { res.setHeader("Content-Type", "text/html; charset=utf-8;"); if (req.url == "/index.html" || req.url == "/") { res.write ( "<h2>HOME</h2>"); } else { res.write("<h2>Not found</h2>"); } res.end(); }) .listen(3000); |
Переадресация в Node.js
Переадресация предполагает отправку статусного кода 301 (постоянная переадресация) или 302 (временная переадресация) и заголовка Location, который указывает на новый адрес.
Например, выполним переадресацию с адреса localhost:3000/ на адрес localhost:3000/newpage (пример отсюда):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import http from "http"; http .createServer(function (request, response) { response.setHeader("Content-Type", "text/html; charset=utf-8;"); if (request.url === "/") { response.statusCode = 302; // временная переадресация // на адрес localhost:3000/newpage response.setHeader("Location", "/newpage"); } else if (request.url == "/newpage") { response.write("New address"); } else { response.statusCode = 404; // адрес не найден response.write("Not Found"); } response.end(); }) .listen(3000); |