Как написать сервер на javascript
Перейти к содержимому

Как написать сервер на javascript

  • автор:

Веб сервер на JavaScript

Уже давно есть возможность написать свой сервер, с нуля на JavaScript, с использованием Node.js движка от браузера Chrome.
В первом моем посте-заметке на хабре, хочу поделиться своим опитом создания самописного сервера.
Так ка я люблю хардкор в програмировании, то когда необходимо било сделать сайт, я решил делать всю серверную часть с нуля! Почему я вибрал JavaScript? — дело в том что мне также необходимо било запрограмировать и сам сайт (странички хтмл). И как Вы догадались, и там и там один и тот же язык — JavaScript, что несомненно является плюсом для разработчика, так как не надо изучать и понимать десять разных синтаксесов и парадигм языков.

Веб сервер в две строки кода

Напишем пару строчек кода и создадим собственный веб сервер, назовем файл index.js.

var http = require(‘http’);
http.createServer(function (req, res) res.end(‘Hello World\n’);
>).listen(80, ‘localhost’);
console.log(‘Server running at localhost’);

Поясню, сначала подключаем модуль http для собственно веб сервера, далее создаем асинхронную функцию калбек для входящих запросов и на конец то стартуем сервер на 80 порту. Очень просто и все понятно, нет ничего лишнего.

Важно помнить, что Skype может висеть на 80 порту, по этому необходимо убить Skype перед запуском сервера!

Запускаем сервер, с консоли, следующим образом:

Вот и все, переходим в браузер и вводим localhost, в ответ получим Hello World!
Ето только вершина айсберга, в следующих заметках я расскажу более детально как сделать полноценный веб сервер для большого сайта.

Спасибо за внимание!

#7 – Создание своего сервера Node JS

#7 – Создание своего сервера Node JS

На основе лишь одного Node JS вы легко можете создать свой сервер. Такой сервер может работать с пользователем, отслеживать URL адреса и показывать пользователю разные страницы сайта.

Видеоурок

Благодаря модулю http можно создавать и подключаться к серверу буквально за пару строчек кода. В ходе урока мы создали локальный сервер, на котором вывели текст без использования HTML-тегов .

Для создания сервера необходимо подключиться к модулю http и использовать метод createServer . В метод необходимо поместить функцию с двумя параметрами: request (запрос) и response (ответ).

В параметре response мы можем установить какие заголовки должен вернуть сервер, а также что должно быть отображено на странице сайта.

В заголовках мы указываем типы данных, которые мы хотим передать и отобразить на сайте. В данный момент мы работаем с простым типом данных, а именно с обычным текстом — text/plain . При работе с заголовками важно указать кодировку, чтобы текст написанный на кириллице выводился корректно.

Для вывода информации в браузере используйте метод end :

const http = require('http') // Необходимый модуль // Создание сервера const server = http.createServer((req, res) => < // Указание заголовков (тип данных и кодировка) res.writeHead(200, ) // Текст, который будет отображен на странице res.end('Просто обычный текст без HTML') >)

Также необходимо установить само соединение, в котором указать порт, а также адрес сервера. В нашем случае мы используем локальные параметры:

// server - переменная созданная ранее server.listen(3000, '127.0.0.1')

Если запустить программу и зайти на адрес 127.0.0.1:3000 , то на сайте будет надпись: «Просто обычный текст без HTML».

Сервер

Для работы с сервером и протоколом http в Node.js используется модуль http.

Чтобы создать сервер, следует вызвать метод http.createServer() :

const http = require("http"); const server = http.createServer();

Метод createServer() возвращает объект http.Server . Для обработки подключений в метод createServer передается функция-обработчик:

const http = require("http"); const server = http.createServer(function(request, response)< response.end("Hello METANIT.COM!"); >);

Эта функция принимает два параметра:

  • request : хранит информацию о запросе
  • response : управляет отправкой ответа

В примере выше с помощью метода response.end() в ответ клиенту посылается строка «Hello METANIT.COM!».

Но чтобы сервер мог прослушивать и обрабатывать входящие подключения, у объекта сервера необходимо вызвать метод listen() . Данный метод может принимать различный набор параметров. Но обычно в качестве первого параметра передается номер порта, по которому запускается сервер.

const http = require("http"); const server = http.createServer(function(request, response)< response.end("Hello METANIT.COM!"); >); server.listen(3000);

В данном случае сервер запускается по адресу 3000. Также дополнительно можно передать в метод listen функцию, которая будет срабатывать при запуске сервера:

const http = require("http"); const server = http.createServer(function(request, response)< response.end("Hello METANIT.COM!"); >); server.listen(3000, function()< console.log("Сервер запущен по адресу http://localhost:3000")>);

Например, запустим приложение, и после успешного запуска мы увидим на консоли соответствующее сообщение:

c:\app> node app.js Сервер запущен по адресу http://localhost:3000

Поскольку сервер запущен на порту 3000, то мы можем обратиться к нашему приложению в браузере по адресу http://localhost: 3000

Создание сервера на Node.js

Request

Параметр request позволяет получить информацию о запросе и представляет объект http.IncomingMessage . Отметим некоторые основные свойства этого объекта:

  • headers : возвращает заголовки запроса
  • method : тип запроса (GET, POST, DELETE, PUT)
  • url : представляет запрошенный адрес

Например, определим следующий файл app.js:

const http = require("http"); http.createServer(function(request, response)< console.log("Url:", request.url); console.log("Тип запроса:", request.method); console.log("User-Agent:", request.headers["user-agent"]); console.log("Все заголовки"); console.log(request.headers); response.end(); >).listen(3000, function()< console.log("Сервер запущен по адресу http://localhost:3000")>);

Запустим его и обратимся в браузере по адресу http://localhost:3000/ , и консоль выведет нам информацию о запросе:

c:\app> Сервер запущен по адресу http://localhost:3000 Url: / Тип запроса: GET User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Все заголовки < host: 'localhost:3000', connection: 'keep-alive', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'sec-purpose': 'prefetch;prerender', purpose: 'prefetch', accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'sec-fetch-site': 'none', 'sec-fetch-mode': 'navigate', 'sec-fetch-user': '?1', 'sec-fetch-dest': 'document', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,fr;q=0.6,de;q=0.5,tr;q=0.4,zh-CN;q=0.3,zh;q=0.2,bg;q=0.1' >

Response

Параметр response управляет отправкой ответа и представляет объект http.ServerResponse . Среди его функциональности можно выделить следующие методы:

  • statusCode : устанавливает статусный код ответа
  • statusMessage : устанавливает сообщение, отправляемое вместе со статусным кодом
  • setHeader(name, value) : добавляет в ответ один заголовок
  • write : пишет в поток ответа некоторое содержимое
  • writeHead : добавляет в ответ статусный код и набор заголовков
  • end : сигнализирует серверу, что заголовки и тело ответа установлены, в итоге ответ отсылается клиента. Данный метод должен вызываться в каждом запросе.

В общем случае для отправки ответа достаточно вызвать метод end() , в который передаются отправляемые данные:

response.end("Hello METANIT.COM!");

С помощью метода write() можно кусками добавить данные в ответ. Например, изменим файл app.js следующим образом:

const http = require("http"); http.createServer(function(request, response)< response.write("Text 1\n"); response.write("Text 2\n"); response.end("End"); >).listen(3000, function()< console.log("Сервер запущен по адресу http://localhost:3000")>);

Запустим файл и обратимся в браузере к приложению:

Отправка ответа в Node.js

Можно через end() ничего не добавлять в ответ, но в любом случае этот метод следует вызывать при отправке ответа:

const http = require("http"); http.createServer(function(_, response)< response.write("Text 1\n"); response.write("Text 2\n"); response.end(); >).listen(3000, function()< console.log("Сервер запущен по адресу http://localhost:3000")>);
Отправка заголовков

Метод setHeader() позволяет установить заголовки ответа:

const http = require("http"); http.createServer(function(_, response)< response.setHeader("UserId", 12); // установка кастомного заголовка response.setHeader("Content-Type", "text/html; charset=utf-8;"); response.write("

Привет мир

"); response.end(); >).listen(3000, function()< console.log("Сервер запущен по адресу http://localhost:3000")>);

В данном случае для теста устанавливаем кастомный заголовок «UserId», пусть он равен 12. А чтобы отправляемый ответ интерпретировался браузером как код html, для заголовка «Content-Type» устанавливаем значение «text/html; charset=utf-8;». Результат работы:

Отправка заголовков в Node.js

Маршрутизация

По умолчанию Node.js не имеет встроенной системы маршрутизации. Обычно она реализуется с помощью специальных фреймворков типа Express, о котором речь пойдет в следующей главе. Однако если необходимо разграничить простейшую обработку пары-тройки маршрутов, то вполне можно использовать для этого свойство url объекта Request. Например:

const http = require("http"); http.createServer(function(request, response)< response.setHeader("Content-Type", "text/html; charset=utf-8;"); if(request.url === "/home" || request.url === "/")< response.write("

Home

"); > else if(request.url == "/about")< response.write("

About

"); > else if(request.url == "/contact")< response.write("

Contacts

"); > else< response.write("

Not found

"); > response.end(); >).listen(3000);

В данном случае обрабатываются три маршрута. Если идет обрашение к корню сайта или по адресу localhost:3000/home , то пользователю выводится строка «Home». Ели обращение идет по адресу localhost:3000/about , то пользователю в браузере отображается строка About и так далее. Если запрошенный адрес не соответствует ни одному маршруту, то выводится заговлок «Not Found».

Маршрутизация в Node.js

Однако опять же отмечу, что рамках специальных фреймворков, которые работают поверх Node.js, например, Express, есть более удобные способы для обработки маршрутов, которые нередко и используются.

Переадресация

Переадресация предполагает отправку статусного кода 301 (постоянная переадресация) или 302 (временная переадресация) и заголовка Location , который указывает на новый адрес. Например, выполним переадресацию с адреса localhost:3000/ на адрес localhost:3000/newpage

const http = require("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);

Node.js server without a framework

Здесь вы найдёте описание простого статического сервера, который построен сугубо на Node.js без использования какого-либо фреймворка .

Node.js может использовать множество фреймворков, которые могут помочь создать сервер

  • Express: Один из наиболее популярных фреймворков.
  • Hapi.js: Набирающий популярность фреймворк для построения приложений и сервисов
  • Total: Этот фреймворк имеет богатую функциональность и не требует каких-либо дополнительных фреймворков или библиотек.

Конечно-же эти фреймворки могут и не подойти для каждого конкретного случая. Именно поэтому нужно знать как все работает изнутри, чтобы быть готовым сделать свой собственный сервер без каких-либо дополнительных зависимостей.

Пример

Вот так выглядит статический сервер на Node.js:

var http = require("http"); var fs = require("fs"); var path = require("path"); http .createServer(function (request, response)  console.log("request ", request.url); var filePath = "." + request.url; if (filePath == "./")  filePath = "./index.html"; > var extname = String(path.extname(filePath)).toLowerCase(); var mimeTypes =  ".html": "text/html", ".js": "text/javascript", ".css": "text/css", ".json": "application/json", ".png": "image/png", ".jpg": "image/jpg", ".gif": "image/gif", ".svg": "image/svg+xml", ".wav": "audio/wav", ".mp4": "video/mp4", ".woff": "application/font-woff", ".ttf": "application/font-ttf", ".eot": "application/vnd.ms-fontobject", ".otf": "application/font-otf", ".wasm": "application/wasm", >; var contentType = mimeTypes[extname] || "application/octet-stream"; fs.readFile(filePath, function (error, content)  if (error)  if (error.code == "ENOENT")  fs.readFile("./404.html", function (error, content)  response.writeHead(404,  "Content-Type": "text/html" >); response.end(content, "utf-8"); >); > else  response.writeHead(500); response.end( "Sorry, check with the site admin for error: " + error.code + " ..\n", ); > > else  response.writeHead(200,  "Content-Type": contentType >); response.end(content, "utf-8"); > >); >) .listen(8125); console.log("Server running at http://127.0.0.1:8125/"); 

Задание

Попробуйте добавить в этот код описание как работает этот код. Как вариант ещё можно добавить функциональность динамических запросов.

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *