Skip to content

Commit 299ab00

Browse files
committed
fix(@angular/ssr): preserve response headers during redirect
Previously, when a redirect was triggered, any custom headers (such as cookies or cache control) configured on the RESPONSE_INIT object by components or guards were lost because the redirect response was created with the default headers only. Closes #33473
1 parent 010cef6 commit 299ab00

3 files changed

Lines changed: 8 additions & 3 deletions

File tree

packages/angular/ssr/src/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ export class AngularServerApp {
353353
}
354354

355355
if (result.redirectTo) {
356-
return createRedirectResponse(result.redirectTo, responseInit.status, headers);
356+
return createRedirectResponse(result.redirectTo, responseInit.status, responseInit.headers);
357357
}
358358

359359
if (renderMode === RenderMode.Prerender) {

packages/angular/ssr/src/utils/redirect.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function isValidRedirectResponseCode(code: number): boolean {
3333
export function createRedirectResponse(
3434
location: string,
3535
status = 302,
36-
headers?: Record<string, string>,
36+
headers?: Record<string, string> | Headers,
3737
): Response {
3838
if (ngDevMode && !isValidRedirectResponseCode(status)) {
3939
throw new Error(
@@ -42,7 +42,7 @@ export function createRedirectResponse(
4242
);
4343
}
4444

45-
const resHeaders = new Headers(headers);
45+
const resHeaders = headers instanceof Headers ? headers : new Headers(headers);
4646
if (ngDevMode && resHeaders.has('location')) {
4747
// eslint-disable-next-line no-console
4848
console.warn(

packages/angular/ssr/test/app_spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ describe('AngularServerApp', () => {
4242
const responseInit = inject(RESPONSE_INIT);
4343
if (responseInit) {
4444
responseInit.status = 308;
45+
const headers = responseInit.headers;
46+
if (headers) {
47+
(headers as Headers).set('X-Redirect-Header', 'custom-value');
48+
}
4549
}
4650

4751
void inject(Router).navigate([], {
@@ -326,6 +330,7 @@ describe('AngularServerApp', () => {
326330
const response = await app.handle(new Request('http://localhost/redirect-via-navigate'));
327331
expect(response?.headers.get('location')).toBe('/redirect-via-navigate?filter=test');
328332
expect(response?.status).toBe(308);
333+
expect(response?.headers.get('X-Redirect-Header')).toBe('custom-value');
329334
});
330335

331336
it('returns a 302 status and redirects to the correct location when `urlTree` is updated in a guard', async () => {

0 commit comments

Comments
 (0)