Angular SSR场景下如何从服务端获取客户端域名
在Angular SSR中获取客户端真实域名的方案
核心思路
SSR场景下,服务端可直接读取HTTP请求头里的Host字段(无反向代理时)或X-Forwarded-Host字段(部署了Nginx等反向代理时),这两个字段会携带客户端实际访问的域名,能避开request.origin返回服务端路径的问题。
具体实现步骤
1. 在Server.ts中传递请求头信息到Angular应用
修改SSR入口文件server.ts,渲染应用时把请求的真实域名注入到Angular的依赖注入系统中:
import { APP_BASE_HREF } from '@angular/common'; import { ngExpressEngine } from '@nguniversal/express-engine'; import express from 'express'; import { existsSync } from 'fs'; import { join } from 'path'; import { AppServerModule } from './src/main.server'; const app = express(); const PORT = process.env['PORT'] || 4000; const DIST_FOLDER = join(process.cwd(), 'dist/browser'); app.engine('html', ngExpressEngine({ bootstrap: AppServerModule, })); app.set('view engine', 'html'); app.set('views', DIST_FOLDER); app.get('*.*', express.static(DIST_FOLDER, { maxAge: '1y' })); app.get('*', (req, res) => { // 优先取反向代理传递的X-Forwarded-Host,再取原生Host const clientDomain = req.headers['x-forwarded-host'] || req.headers.host; res.render('index', { req, res, providers: [ { provide: APP_BASE_HREF, useValue: req.baseUrl }, // 注入自定义令牌,将客户端域名传给Angular应用 { provide: 'CLIENT_DOMAIN', useValue: clientDomain } ] }); }); app.listen(PORT, () => { console.log(`Node Express server listening on http://localhost:${PORT}`); });
2. 在Angular组件/服务中使用客户端域名
在需要获取域名的组件或服务里,通过@Inject注入自定义令牌:
import { Component, Inject, Optional } from '@angular/core'; @Component({ selector: 'app-frontpage', templateUrl: './frontpage.component.html', }) export class FrontpageComponent { clientDomain: string; constructor( @Optional() @Inject('CLIENT_DOMAIN') private domain: string ) { // 兜底处理,避免请求头缺失时出现空值 this.clientDomain = domain || 'default-domain.com'; console.log('当前客户端访问域名:', this.clientDomain); // 示例输出:www.example.org } }
3. 反向代理场景的补充配置(以Nginx为例)
如果应用部署在Nginx之后,需在Nginx配置中添加X-Forwarded-Host头,确保服务端能拿到真实域名:
server { listen 80; server_name example.com example.org example.net www.example.com www.example.org www.example.net; location / { proxy_pass http://your-angular-ssr-server:4000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
注意事项
- 绝对不要依赖
window.location.host,SSR阶段该对象不存在,会直接导致报错。 - 若未使用反向代理,直接读取
req.headers.host即可,它会返回客户端请求时携带的完整域名(含非80/443端口)。 - 必须添加兜底逻辑,防止请求头缺失时出现空值问题。
内容的提问来源于stack exchange,提问作者Efisio Pitzalis Morillas
相关产品推荐
相关产品推荐

