簡體   English   中英

Express 中基於子域(主機)的路由

[英]Subdomain (host) based routing in Express

我已經谷歌搜索了一段時間,但找不到任何有用的答案。 我正在嘗試在我的網站api.example.com上獲取 api 的子域。 但是,所有答案都說我需要更改我的 DNS 以將api.example.com重定向到example.com/api ,這是我不想要的。 是否可以只提供api.而不是重定向到/api 我將如何 go 這樣做?

  1. 我正在使用快遞。
  2. 我不想使用任何其他非內置的包。
const path = require('path'),
      http = require('http'),
      https = require('https'),
      helmet = require('helmet'),
      express = require('express'),
      app = express();

const mainRouter = require('./routers/mainRouter.js');

// security improvements
app.use(helmet());

// main pages
app.use('/', mainRouter);

// route the public directory
app.use(express.static('public'));

app.use(/* API subdomain router... */)

// 404s
app.use((req, res) => {
    res.status(404).sendFile(path.join(__dirname, "views/404.html"));
})

我建議您使用Nginx和單獨的api服務。

但是由於某些原因,您無法避免它(或者您不想要它,因為您只想盡快向客戶展示原型)。

您可以編寫中間件,該中間件將從標頭中捕獲主機並轉發到某些自定義路由器:

1) /middlewares/forwardForSubdomain.js

module.exports = 
    (subdomainHosts, customRouter) => {
      return (req, res, next) => {
        let host = req.headers.host ? req.headers.host : ''; // requested hostname is provided in headers
        host = host.split(':')[0]; // removing port part

        // checks if requested host exist in array of custom hostnames
        const isSubdomain = (host && subdomainHosts.includes(host));
        if (isSubdomain) { // yes, requested host exists in provided host list
          // call router and return to avoid calling next below
          // yes, router is middleware and can be called
          return customRouter(req, res, next); 
        }

        // default behavior
        next();
      }
    };

2)以api路由器為例/routers/apiRouter.js

const express = require('express');
const router = express.Router();

router.get('/users', (req, res) => {
  // some operations here
});

module.exports = router;

3)在/處理程序之前附加中間件:

const path = require('path'),
      http = require('http'),
      https = require('https'),
      helmet = require('helmet'),
      express = require('express'),
      app = express();

const mainRouter = require('./routers/mainRouter');

// security improvements
app.use(helmet());

// ATTACH BEFORE ROUTING
const forwardForSubdomain = require('./middlewares/forwardForSubdomain');
const apiRouter = require('./routers/apiRouter');
app.use(
  forwardForSubdomain(
    [
      'api.example.com',
      'api.something.com'
    ],
    apiRouter
  )
);

// main pages
app.use('/', mainRouter);

// route the public directory
app.use(express.static('public'));

// 404s
app.use((req, res) => {
    res.status(404).sendFile(path.join(__dirname, "views/404.html"));
})

PS它與express-vhost中的代碼相同

Express.js 有一個官方的 vhost 插件: https://github.com/expressjs/vhost

您所描述的由單個服務器托管/處理的多個域/主機名通常稱為“vhost”(虛擬主機)。

絕對可以僅將子域(api.example.com)指向您的api服務器。

DNS無法控制子目錄,因此example.com/api的DNS條目無效

如果您有服務器的IP地址,則需要添加一個A記錄,其值是: api.example.com

如果您擁有服務器的域名,則需要創建一個CNAME記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM