You need to enable JavaScript to run this app. Node.js 与 Angular 的 HTTPS 端口冲突及 Apache /api 反向代理配置
优惠活动
大模型
产品
解决方案
定价
更多

Node.js 与 Angular 的 HTTPS 端口冲突及 Apache /api 反向代理配置

解决步骤

1. 前端和 Node 服务可以共用同一个域名

可以。浏览器只访问 Apache 的 443 端口,由 Apache 根据路径区分:

  • https://www.yourdomain.com/:Angular 前端
  • https://www.yourdomain.com/api/...:反向代理到 Node.js 服务

Node.js 的 8080 或 8443 端口不需要暴露给公网,浏览器也不会直接连接这些端口。


2. 推荐做法:Apache 终止 HTTPS,Node 仅监听本地 HTTP

生产环境中,如果 Apache 和 Node.js 在同一台服务器上,常见做法是:

  1. 浏览器到 Apache 使用 HTTPS。
  2. Apache 到本机 Node.js 使用普通 HTTP。
  3. Node.js 只监听 127.0.0.1,不接受公网连接。

因为流量只经过本机回环地址,不需要再封装一层 TLS。这样也只需要在 Apache 上配置一张公开证书。

修改 Node.js:

const http = require('http');

// app 是 Express 实例
app.set('trust proxy', 'loopback');

http.createServer(app).listen(8080, '127.0.0.1', () => {
  console.log('Node.js listening on http://127.0.0.1:8080');
});

这里可以删除 Node 中读取 server.key、server.crt、server.pem 并创建 HTTPS 服务的代码。


3. 修改 Apache 的 443 VirtualHost

确保启用代理模块:

sudo a2enmod proxy proxy_http headers
sudo apache2ctl configtest
sudo systemctl restart apache2

推荐配置如下:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com

    Redirect 301 / https://www.yourdomain.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName www.yourdomain.com
    ServerAlias yourdomain.com

    DocumentRoot /var/www/your-angular-app

    SSLEngine on
    SSLCertificateFile      /etc/ssl/private/server.crt
    SSLCertificateKeyFile   /etc/ssl/private/server.key
    SSLCACertificateFile    /etc/ssl/private/gd_bundle.crt

    ProxyRequests Off
    ProxyPreserveHost On

    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"

    ProxyPass        /api http://127.0.0.1:8080/api
    ProxyPassReverse /api http://127.0.0.1:8080/api

    <Directory /var/www/your-angular-app>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

注意:

  • 把 yourdomain.com 和 /var/www/your-angular-app 替换成实际值。
  • gd_bundle.crt 应是 GoDaddy 提供的中间证书链,不要把站点证书本身重复放在这里。
  • 如果证书不包含 www.yourdomain.com,浏览器访问 www 时仍会报证书错误。一张证书可以通过 SAN 同时包含 yourdomain.com 和 www.yourdomain.com,必要时让 GoDaddy 重新签发。
  • Angular 前端应使用相对路径 /api 请求接口,不要写 https://IP:8443。

上面的配置假设 Express 路由本身带有 /api 前缀,例如:

app.get('/api/users', ...);

如果 Express 路由不带 /api,而是 /users,则应使用下面的写法把前缀去掉:

ProxyPass        /api/ http://127.0.0.1:8080/
ProxyPassReverse /api/ http://127.0.0.1:8080/

ProxyPass        /api http://127.0.0.1:8080
ProxyPassReverse /api http://127.0.0.1:8080

4. 防止 Angular 把 /api 重写成 index.html

如果 Angular 的 .htaccess 中有把所有路径重写到 index.html 的规则,需要排除 /api:

RewriteCond %{REQUEST_URI} !^/api
RewriteRule ^ index.html [L]

否则代理可能没有被正确命中,请求最终仍返回 Angular 的 index.html。


5. 为什么原来的 HTTPS 代理配置不生效

你之前的配置:

ProxyPass /api https://myip:8443/api

有两个问题:

  1. Apache 作为代理客户端连接 HTTPS 后端时,需要配置:

    SSLProxyEngine On
    
  2. 证书签发给的是域名,而不是 IP。连接 https://myip:8443 时,证书中的域名和访问地址不匹配,Apache 会拒绝后端连接。

即使加上 SSLProxyEngine On,直接使用 IP 仍会产生证书主机名校验错误。生产环境不建议通过关闭校验绕过。


6. 如果 Apache 和 Node 不在同一台机器

如果后端网络不可信,仍然建议 Apache 到 Node.js 使用 HTTPS。此时应:

  • 使用内部 CA 给 Node 签发包含内部主机名的证书;
  • Apache 配置 SSLProxyEngine On;
  • 使用能和证书 SAN 匹配的主机名,而不是公网 IP;
  • 不要关闭证书校验。

示例:

SSLProxyEngine On
SSLProxyCACertificateFile /etc/ssl/private/internal-ca.pem

ProxyPass        /api https://node.internal:8443/api
ProxyPassReverse /api https://node.internal:8443/api

如果证书使用 IP 访问,则证书必须包含对应的 IP SAN。不要在生产环境使用 SSLProxyVerify none 或关闭 PeerName 校验。

最终答案

修改 443 端口的 VirtualHost,在其中加入反向代理;Node.js 改为只监听 127.0.0.1:8080 的 HTTP 服务。浏览器继续访问 https://www.yourdomain.com/api,Apache 会把该路径转发到本机 Node.js,Angular 则处理其他路径。一张公开 SSL 证书只需要安装在 Apache 上,Node.js 不需要直接暴露 8443 端口,也不需要使用 IP 访问。

内容的提问来源于 stack exchange,提问作者 Nosk48

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 06:45:04