如何使用 Apache 将子域主机转发到 proxypass?

How to forward subdomain host to proxypass with Apache?

我的节点服务器正在侦听 127.0.0.1:7676。但是,它会根据子域做出不同的响应。使用标准 ProxyPass 配置(如下),子域被剥离。

如何将子域转发到节点服务器?

示例 1:基本代理配置:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias *.example.com

    ProxyPass / http://localhost:7676/

</VirtualHost>

示例 2:尝试为所有请求传递一个简单的 "test" 子域

<VirtualHost *:80>
    ServerName example.com
    ServerAlias *.example.com

    RequestHeader set "Host" "test.example.com"
    ProxyPass / http://localhost:7676/

</VirtualHost>

我的尝试(示例 2)无效。节点服务器仍然看不到子域。即使它确实有效,我也需要它是动态的(获取请求的任何子域并将其传递给节点服务器)。

请注意,可以有多个子域 (test2.test1.example.com)。

经过反复试验,我弄明白了。

示例 2 的问题在于,Apache 决定隐式设置 "X-Forwarded-Host" header,而不是设置 "Host" header。老实说,我宁愿它出错而不是默默地设置一个不同的 header,但是没关系。

但是,为了转发主机(获取请求的任何子域并将其传递给节点服务器),我们可以使用 Apache 的得心应手的花花公子 ProxyPreserveHost On,记录在案 here.

这会将 "X-Forwarded-Host" 设置为请求的主机。


以下是依赖于实现的。我在 Express 中使用了 Node。

以下是我执行检查的方式:

function getSubDomains(host, offset = 2) {
    const split = host.split(".").reverse();
    return split.slice(2);
}

router.all('*', function (req, res, next) {
    const subdomains = getSubDomains(req.get("X-Forwarded-Host"));
    // code to use subdomains

你是在问我为什么不直接覆盖 req.subdomains?出于某种原因,它不起作用,所以我就这样做了。

最后,我添加了一个快速检查以确保域是我的。但这可能不是必需的。

function getSubDomains(host, offset = 2) {
    const split = host.split(".").reverse();
    if (split[0] !== "com" || split[1] !== "example") { // for *.example.com
        return false;
    }
    return split.slice(2);
}


router.all('*', function (req, res, next) {
    const subdomains = getSubDomains(req.get("X-Forwarded-Host"));
    if (!subdomains) {
        res.send("Huh?");
        return;
    }