You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular SSR(v18)服务端请求未携带Cookie问题排查

问题背景

用Angular原生SSR(非Angular Material)时遇到棘手问题:页面刷新后,服务端发起的首个API请求没带Cookie,导致拿不到用户数据。试过ngx-cookie-service-ssr@18.0.0,也在server.ts里配置了REQUEST和RESPONSE提供者,app.config.ts也注册了SsrCookieService,但就是没效果。

已做配置

1. server.ts 提供者配置

providers: [
  { provide: APP_BASE_HREF, useValue: baseUrl },
  { provide: 'REQUEST', useValue: req },
  { provide: 'RESPONSE', useValue: res },
]

2. app.config.ts 服务注册

export const appConfig: ApplicationConfig = {
  providers: [
    SsrCookieService,
    // 其他提供者...
  ]
}

问题排查与解决步骤

HttpOnly Cookie确实没法被前端JS读取,但SSR服务端渲染阶段,直接从请求对象里拿Cookie,手动加到API请求头就行——根本不需要前端JS读取Cookie。

得在服务端API调用的拦截器或者服务里,注入REQUEST对象,提取Cookie后附加到请求头:

import { Inject, Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';

@Injectable()
export class ServerCookieInterceptor implements HttpInterceptor {
  constructor(@Inject('REQUEST') private request: any) {}

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    // 只在服务端渲染时处理
    if (typeof window === 'undefined') {
      const cookieHeader = this.request.headers.cookie;
      if (cookieHeader) {
        req = req.clone({
          setHeaders: {
            Cookie: cookieHeader
          }
        });
      }
    }
    return next.handle(req);
  }
}

然后在app.config.ts里注册这个拦截器,用provideHttpClient(withInterceptors([ServerCookieInterceptor]))即可。

别直接在app.config.ts里注册SsrCookieService,改用工厂提供者区分环境,确保服务端能拿到正确的REQUEST对象:

// app.config.ts
import { ApplicationConfig, FactoryProvider } from '@angular/core';
import { SsrCookieService } from 'ngx-cookie-service-ssr';

const cookieServiceProvider: FactoryProvider = {
  provide: SsrCookieService,
  useFactory: (request?: any, response?: any) => {
    return new SsrCookieService(request, response);
  },
  deps: [['REQUEST', { optional: true }], ['RESPONSE', { optional: true }]]
};

export const appConfig: ApplicationConfig = {
  providers: [
    cookieServiceProvider,
    // 其他提供者...
  ]
};

3. 子域名API的Cookie共享问题

前端域名是diecasttracker.com,API是api.diecasttracker.com,属于子域名跨域,得确保:

  • Cookie设置时指定Domain=.diecasttracker.com,让子域名能共享;
  • API请求要开withCredentials: true(不管是浏览器还是服务端请求);
  • 后端CORS配置要允许credentials,且Access-Control-Allow-Origin设为具体域名(不能用*)。
    服务端请求虽然没浏览器跨域限制,但如果Cookie的Domain不对,后端API也认不出来,所以一定要检查Cookie的Domain配置。

4. Nginx 配置调整

前后端在同一VPS的话,Nginx反向代理要确保Cookie正确传递:

# 前端SSR服务配置
server {
  listen 443 ssl;
  server_name diecasttracker.com;

  location / {
    proxy_pass http://localhost:4000; # 替换成你的Angular SSR端口
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Cookie $http_cookie; # 关键:把Cookie传给SSR服务
    proxy_http_version 1.1;
  }

  # SSL相关配置...
}

# API服务配置
server {
  listen 443 ssl;
  server_name api.diecasttracker.com;

  location /api {
    proxy_pass http://localhost:3000; # 替换成你的后端API端口
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Cookie $http_cookie; # 把Cookie传给后端API
    proxy_http_version 1.1;
  }

  # SSL相关配置...
}

额外检查项

  • 在server.ts里打印req.headers.cookie,确认服务端能拿到用户的认证Cookie;
  • 检查API请求的域名是否正确,服务端请求别用localhost,避免Cookie不匹配;
  • 确认Cookie的Path设为/,保证所有路径都能访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:29:51