Как работает файловый сервер Node.js

Node.js позволяет загружать страницы или приложения из браузера с помощью простого серверного сценария.

Представленный нами скрипт ничем не отличается по своей работе от различных скриптов, опубликованных на официальном сайте или в разных «учебниках» или псевдоуроках на Node.
Я говорю о псевдоуроке, потому что программисты, как правило, не делают разницы между учебником, который объясняет, как использовать вещь, и учебником, который изучает ее работу, проходя поэтапно и переходя от самого простого к самому сложному. Когда программист добавляет комментарии к листингу, это «учебник». Мы далеки от этого, а сам исходный код написан, чтобы его легко понять?
Особенно показательно это в случае с Node.js, где все демонстрационные скрипты написаны в рекурсивной форме, которая заставляет читателя мыслить как процессор, что кажется конечной целью хакера.

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

1) Создание сервера

var server = http.createServer(getFilename);
server.listen(1000);
console.log("Server available...");

Параметр createServer - это обратный вызов, который будет включен при входе браузера в порт 1000 с именем файла в качестве параметра. Вводя, например, в панель браузера :

127.0.0.1:1000/page.html

2) Анализ URL и передача имени файла в систему

function getFilename(request, response)
{
  var urlpath = url.parse(request.url).pathname;
  var localpath = path.join(process.cwd(), urlpath);
  fs.exists(localpath, function(result) { getFile(result, response, localpath)});
}

Эта функция извлекает путь из URL-адреса и передает этот параметр второй функции, которая считывает файл на локальном сервере или компьютере.
Для этого используются модули url и path.

3) Чтение файла

function getFile(exists, response, localpath)
{
  if(!exists) return sendError(404, '404 Not Found', response);
  fs.readFile(localpath, "binary",
    function(err, file){ sendFile(err, file, response);});
}

Файл считывается с помощью модуля fs, который выполняет обычные операции в файловой системе, за исключением выполнения программ, для которых требуется другой модуль. Наша функция sendFile вызывается readFile модуля fs.

4) Отправить страницу

function sendFile(err, file, response)
{
  if(err) return sendError(500, err, response);
  response.writeHead(200);
  response.write(file, "binary");
  response.end();
} 

Содержимое файла отправляется в браузер, который его отображает. Это выполняется ответным объектом, созданным вместе с сервером и переданным каждой функции.

5) Перечень полезных модулей

http = require("http");
path = require("path");
url = require("url");
fs = require("fs");

Роль каждого из них была замечена ранее, за исключением HTTP, что позволяет использовать протокол HTTP для обмена данными между сервером и браузером (или другим пользовательским агентом).

6) Полный

сценарий:
http = require("http"),
path = require("path"),
url = require("url"),
fs = require("fs");

function sendError(errCode, errString, response)
{
  response.writeHead(errCode, {"Content-Type": "text/plain"});
  response.write(errString + "\n");
  response.end();
  return;
}

function sendFile(err, file, response)
{
  if(err) return sendError(500, err, response);
  response.writeHead(200);
  response.write(file, "binary");
  response.end();
}

function getFile(exists, response, localpath)
{
  if(!exists) return sendError(404, '404 Not Found', response);
  fs.readFile(localpath, "binary",
   function(err, file){ sendFile(err, file, response);});
}

function getFilename(request, response)
{
  var urlpath = url.parse(request.url).pathname; // following domain or IP and port
  var localpath = path.join(process.cwd(), urlpath); // if we are at root
  fs.exists(localpath, function(result) { getFile(result, response, localpath)});
}

var server = http.createServer(getFilename);
server.listen(1000);
console.log("Server available...");  

Этот базовый сервер можно проверить, загрузив файл page.html, содержащийся в архиве. Исходным кодом сценария является файл server.js.

Ранее: Введение в Node.js. Описание системы и заинтересованность в ее использовании .
В следующей статье показано, как использовать Node.js для выполнения PHP-скриптов локально из браузера.