首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Express中基于子域(主机)的路由

Express中基于子域(主机)的路由
EN

Stack Overflow用户
提问于 2019-02-21 00:57:03
回答 2查看 1.9K关注 0票数 2

我已经用谷歌搜索了一段时间,但是找不到任何有用的答案。我正在尝试在我的网站api.example.com上获得一个应用编程接口的子域。然而,所有的回答都说我需要更改我的域名系统,将api.example.com重定向到example.com/api,这是我不想要的。有没有可能不重定向到/api而只服务于api.?我该怎么做呢?

  1. 我正在使用Express.
  2. 我不想使用任何其他不是内置的包。

代码语言:javascript
复制
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"));
})
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-21 01:15:26

建议您使用nginx和单独的api服务。

但由于某些原因,你无法避免它(或者你不想要它,因为你只是想尽快向客户展示原型)。

您可以编写中间件来从报头捕获主机并将其转发到某个自定义路由器:

1) /middlewares/forwardForSubdomain.js

代码语言:javascript
复制
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

代码语言:javascript
复制
const express = require('express');
const router = express.Router();

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

module.exports = router;

3)在/处理程序之前附加中间件:

代码语言:javascript
复制
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"));
})

附注:它的功能与express-vhost包中的look at the code相同

票数 6
EN

Stack Overflow用户

发布于 2019-02-21 00:58:45

只将子域(api.example.com)指向您的api服务器是绝对可能的。

DNS不控制子目录,因此example.com/api的DNS条目将无效

如果您的服务器有一个IP地址,则需要添加值为:api.example.com的A记录。

如果您的服务器有域名,则需要创建一个CNAME记录。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54791634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档