Ответ
Виртуальный хостинг (virtual hosting) — это метод, позволяющий обслуживать несколько доменных имен (например, `api.example.com` и `admin.example.com`) или независимых веб-сайтов на одном физическом сервере с одним IP-адресом и одним запущенным экземпляром приложения Node.js. Механизм основан на анализе HTTP-заголовка `Host`, который клиент отправляет в каждом запросе (это требование HTTP/1.1).
**Как это работает:**
1. DNS для обоих доменов (`api.example.com` и `admin.example.com`) указывает на один IP-адрес сервера.
2. Сервер Node.js получает HTTP-запрос.
3. Приложение проверяет значение `req.headers.host`.
4. В зависимости от значения, запрос маршрутизируется к соответствующей логике или даже к другому внутреннему приложению (микросервису).
**Базовая реализация на чистом Node.js `http` модуле:**
```javascript
const http = require('http');
const apiApp = (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ service: 'API', version: '1.0' }));
};
const adminApp = (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('
Admin Dashboard
');
};
const defaultApp = (req, res) => {
res.writeHead(404);
res.end('Virtual host not found');
};
const server = http.createServer((req, res) => {
const host = req.headers.host;
// Маршрутизация на основе заголовка Host
switch (host) {
case 'api.example.local:3000':
case 'api.example.com':
return apiApp(req, res);
case 'admin.example.local:3000':
case 'admin.example.com':
return adminApp(req, res);
default:
return defaultApp(req, res);
}
});
server.listen(3000, () => {
console.log('Virtual host server running on port 3000');
console.log('Try: http://api.example.local:3000 or http://admin.example.local:3000');
});
```
**Использование специализированного middleware для Express.js:**
Для Express популярным решением является middleware `vhost`. Установите его: `npm install vhost`.
```javascript
const express = require('express');
const vhost = require('vhost');
// Создаем отдельные экземпляры приложений
const apiApp = express();
apiApp.get('/', (req, res) => res.json({ app: 'API' }));
const blogApp = express();
blogApp.get('/', (req, res) => res.send('Blog Homepage'));
// Основное приложение
const mainApp = express();
// Подключаем виртуальные хосты
mainApp.use(vhost('api.example.com', apiApp));
mainApp.use(vhost('blog.example.com', blogApp));
// Обработчик для всех остальных хостов
mainApp.use((req, res) => {
res.status(404).send('Host not configured');
});
mainApp.listen(3000);
```
**Современный подход с прокси-сервером (Nginx, Caddy, Traefik):**
В production-среде виртуальный хостинг чаще реализуется на уровне обратного прокси-сервера перед Node.js приложением. Это более эффективно и гибко.
**Пример конфигурации Nginx:**
```nginx
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3001; # Наше Node.js API приложение
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name admin.example.com;
location / {
proxy_pass http://localhost:3002; # Наше Node.js Admin приложение
proxy_set_header Host $host;
}
}
```
В этом случае каждое Node.js-приложение (`:3001`, `:3002`) может быть независимым и даже написано на разных фреймворках, а Nginx берет на себя маршрутизацию на основе доменного имени.
**Применение виртуальных хостов:**
* **Мультитенантные приложения (SaaS):** `client1.yourapp.com`, `client2.yourapp.com`.
* **Разделение сервисов:** `api.domain.com`, `docs.domain.com`, `app.domain.com`.
* **Стенды для тестирования:** `staging.domain.com`, `qa.domain.com`.