Реализуем статический сервер на NodeJS

Давайте теперь сделаем так, чтобы по URL на нашем сайте искался соответствующий ему HTML файл. Например, если запрашивается /page.html, то мы должны отдать такой же файл, а если запрашивается /dir/test.html, то мы должны отдать файл test.html из папки dir.

Давайте все наши HTML файлы разместим в папке root. Это будет корневая папка нашего сайта и поиск HTML файлов мы будем начинать относительно этой папки.

Реализуем описанное:

http.createServer(async (request, response) => { if (request.url != '/favicon.ico') { let path = 'root' + request.url'; // преобразуем URL в путь к файлу let text = await fs.promises.readFile(path, 'utf8'); response.writeHead(200, {'Content-Type': 'text/html'}); response.write(text); response.end(); } }).listen(3000);

Давайте теперь обработаем URL вида /dir/sub/. Как вы видите, в этом адресе не указано имя файла и его расширение. В интернете принято считать, что такой адрес ссылается на файл index.html, находящийся в этой папке. То есть наш URL следует трактовать как /dir/sub/index.html.

Давайте модифицируем наш код:

http.createServer(async (request, response) => { if (request.url != '/favicon.ico') { let path = 'root' + request.url'; if ((await fs.promises.stat(path)).isDirectory()) { path += 'index.html'; } let text = await fs.promises.readFile(path, 'utf8'); response.writeHead(200, {'Content-Type': 'text/html'}); response.write(text); response.end(); } }).listen(3000);

Если запрошенный URL не соответствует файлу на нашем сайте, очевидно, что мы должны отдавать 404 ошибку. Сделаем это:

http.createServer(async (request, response) => { if (request.url != '/favicon.ico') { let text; let status; let path = 'root' + request.url; try { if ((await fs.promises.stat(path)).isDirectory()) { path += '/index.html'; } status = 200; text = await fs.promises.readFile(path, 'utf8'); } catch (err) { status = 404; text = 'page not found'; } response.writeHead(status, {'Content-Type': 'text/html'}); response.write(text); response.end(); } }).listen(3000);

Рееализуйте описанный статический сервер.

Сделайте так, чтобы 404 страница тоже бралась из файла, например, из файла root/404.html.

При обращении к папке URL со слешем /dir/sub/ и без слеша считаются одинаковым /dir/sub и оба ведут на index папки. Проверьте, как наш сервер справляется с этим. Если есть какие-то проблемы - исправьте их.

Выдача ресурсов

Давайте теперь модифицируем наш сервер так, чтобы кроме HTML файлов, автоматически также выдавались запрошенные ресурсы.

Для начала давайте сделаем функцию, которая будет принимать путь к файлу и по расширению этого файла выдавать его mime тип:

function getMimeType(path) { let mimes = { html: 'text/html', jpeg: 'image/jpeg', jpg: 'image/jpeg', png: 'image/png', svg: 'image/svg+xml', json: 'application/json', js: 'text/javascript', css: 'text/css', ico: 'image/x-icon', }; let exts = Object.keys(mimes); let extReg = new RegExp('\\.(' + exts.join('|') + ')$'); let ext = path.match(extReg)[1]; if (ext) { return mimes[ext]; } else { return 'text/plain'; } }

Имея такую функцию, легко адаптировать наш сервер для выдачи файлов любого типа:

http.createServer(async (request, response) => { let text; let status; let path = 'root' + request.url; try { if ((await fs.promises.stat(path)).isDirectory()) { path += '/index.html'; } status = 200; text = await fs.promises.readFile(path, 'utf8'); } catch (err) { status = 404; text = 'page not found'; } response.writeHead(status, {'Content-Type': getMimeType(path)}); // изменение response.write(text); response.end(); }).listen(3000);

Скопируйте функцию getMimeType из учебника. Исправьте код вашего сервера, используя эту функцию.

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

Убираем расширение из URL

Мы реализовали наш сервер так, что все URL (кроме адресов папок) заканчиваются расширением .html. Однако, в современном мире наличие расширения файла в адресе считается признаком дурного тона и старомодности.

Для красоты необходимо сделать так, чтобы адрес вида /page/ соответствовал файлу root/page.html, адрес вида /dir/page/ - файлу root/dir/page.html, а адрес главной страницы / - файлу root/index.html.

При этом запросы к ресурсам должны работать, как и работали.

Уберите из ваших адресов расширения HTML файлов.