# Реализуем статический сервер на 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 файлов.

←→
↑