Использование Node.js в качестве простого веб-сервера
Я хочу запустить очень простой HTTP-сервер. Каждый GET-запрос к example.com
должен получать index.html
в качестве обычной HTML-страницы (т.е. с таким же опытом, как при чтении обычных веб-страниц).
Используя приведенный ниже код, я могу читать содержимое index.html
. Как мне обслужить index.html
как обычную веб-страницу?
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(index);
}).listen(9615);
Одно из предложений ниже слишком сложное и требует от меня написания строки get
для каждого ресурса (CSS, JavaScript, изображения), который я хочу использовать.
Как мне обслужить одну HTML-страницу с некоторыми изображениями, CSS и JavaScript?
5 ответ(ов)
Вы можете обойтись без Express и Connect. Node.js предоставляет HTTP-функциональность «из коробки». Все, что вам нужно сделать — это вернуть файл в зависимости от запроса. Вот простой пример:
var http = require('http')
var url = require('url')
var fs = require('fs')
http.createServer(function (request, response) {
var requestUrl = url.parse(request.url)
response.writeHead(200)
fs.createReadStream(requestUrl.pathname).pipe(response) // НИКОГДА не используйте синхронные методы fs в production (например, readFileSync)
}).listen(9615)
Вот более полный пример, который гарантирует, что запросы не могут получить доступ к файлам вне базового каталога, и включает в себя обработку ошибок:
var http = require('http')
var url = require('url')
var fs = require('fs')
var path = require('path')
var baseDirectory = __dirname // или любой другой базовый каталог, который вы хотите
var port = 9615
http.createServer(function (request, response) {
try {
var requestUrl = url.parse(request.url)
// Используем path.normalize, чтобы предотвратить доступ к директориям ниже базового каталога
var fsPath = baseDirectory + path.normalize(requestUrl.pathname)
var fileStream = fs.createReadStream(fsPath)
fileStream.pipe(response)
fileStream.on('open', function() {
response.writeHead(200)
})
fileStream.on('error', function(e) {
response.writeHead(404) // предполагаем, что файл не существует
response.end()
})
} catch(e) {
response.writeHead(500)
response.end() // завершаем ответ, чтобы браузеры не зависали
console.log(e.stack)
}
}).listen(port)
console.log("Слушаем на порту " + port)
Этот код обеспечивает базовую реализацию HTTP-сервера с обработкой запросов и ошибками. Следите за тем, чтобы не открывать доступ к файлам вне заданного диска и обрабатывайте ошибки корректно.
Вы, вероятно, упустили важный момент: вы отправляете заголовок:
Content-Type: text/plain
Если вы хотите, чтобы веб-браузер корректно отображал HTML, вам нужно изменить этот заголовок на:
Content-Type: text/html
Чтобы создать простой HTTP-сервер с помощью Express, выполните следующие шаги:
Шаг 1 (в командной строке, убедитесь, что вы перешли в свою папку):
npm install express
Шаг 2: Создайте файл server.js
и добавьте в него следующий код:
var fs = require("fs");
var host = "127.0.0.1";
var port = 1337;
var express = require("express");
var app = express();
app.use(express.static(__dirname + "/public")); // используем статические файлы из папки ROOT/public
app.get("/", function(request, response){ // корневая директория
response.send("Hello!!");
});
app.listen(port, host);
Обратите внимание, что вы должны добавить WATCHFILE
(или использовать nodemon
) для автоматического перезапуска сервера при изменениях в коде. В приведённом коде только базовый сервер.
Шаг 3: Запустите сервер командой:
node server.js
или, если вы используете nodemon
:
nodemon server.js
Если вам нужен более простой способ для запуска простого HTTP-сервера, вы можете использовать пакет http-server
. Для этого выполните команду:
npm install -g http-server
Затем перейдите в вашу директорию и выполните:
http-server
Дополнительную информацию можно найти по ссылке: http-server на npm.
Быстрый способ:
var express = require('express');
var app = express();
app.use('/', express.static(__dirname + '/../public')); // ← измените путь
app.listen(3000, function() { console.log('Слушаем на порту 3000'); });
Ваш способ:
var http = require('http');
var fs = require('fs');
http.createServer(function (req, res) {
console.dir(req.url);
// вы получите '/' или 'index.html' или 'css/styles.css' ...
// • вам нужно выделить расширение
// • иметь небольшой массив/объект для определения типа контента
// • читать файл только тогда, когда это необходимо
// • и передавать его после установки правильного типа контента
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('ok');
}).listen(3001);
В общем, использование Express позволяет вам обойтись без лишней обработки, а также быстро и просто раздавать статические файлы из указанной папки. Если же вы хотите создать сервер, используя чистый Node.js, то это требует большего количества кода для управления файлами и их типами.
Вместо использования оператора switch, я считаю более удобным использовать словарь для получения типа контента по расширению файла:
var contentTypesByExtension = {
'html': "text/html",
'js': "text/javascript"
};
...
var contentType = contentTypesByExtension[fileExtension] || 'text/plain';
Таким образом, если расширение файла не найдено в словаре, будет возвращён тип контента по умолчанию - text/plain
. Это упрощает код и делает его более читаемым.
Как предотвратить установку "devDependencies" модулей NPM для Node.js (package.json)?
Ошибка "npm WARN package.json: Нет поля repository"
Как исправить ошибку "ReferenceError: primordials is not defined" в Node.js
Как протестировать один файл с помощью Jest?
nvm постоянно "забывает" Node.js в новой сессии терминала