SSR route redirects drop the query string on relative `redirectTo`
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- express, nodejs, typescript
Hướng nghiên cứu
Start in packages/angular/ssr/src/app.ts around lines 168-176, where the 302 Location is built from the stored redirectTo and url.search is never read. The reporter notes that redirectTo is already absolute by then, so the code must keep track of whether the redirect was relative, and the router's recognize.ts keeps the original query for relative redirects. Done means the relative case returns the query in Location, the absolute case is unchanged, and the curl command from the report shows /search/results?q=x.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Command
other
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
When a request matches a route with a string redirectTo, @angular/ssr answers with a 302 built from the route config, without running the router. For a relative redirectTo, the query string of the request is dropped.
The Angular router keeps it: a relative redirect only rewrites the matched segments and continues with the rest of the URL. So /search?q=x with { path: '', redirectTo: 'results' } under search ends up at /search/results?q=x with in-app navigation, but at /search/results on a full page load (direct link, reload, link from an email).
For absolute redirects the router drops the query as well, so these already agree.
Minimal Reproduction
npx @angular/[email protected] new repro-app --ssr --defaults
cd repro-app
src/app/app.routes.ts:
import { Component } from '@angular/core';
import { Routes } from '@angular/router';
@Component({ template: 'Results page' })
class Results {}
export const routes: Routes = [
{
path: 'search',
children: [
{ path: '', redirectTo: 'results', pathMatch: 'full' },
{ path: 'results', component: Results },
],
},
];
src/app/app.routes.server.ts (server rendering, so the request reaches the redirect handling instead of a prerendered redirect page):
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [{ path: '**', renderMode: RenderMode.Server }];
npx ng build
NG_ALLOWED_HOSTS=localhost PORT=4000 node dist/repro-app/server/server.mjs
curl -si 'localhost:4000/search?q=x' | grep -i '^location'
Expected: location: /search/results?q=x (where the router navigates). Actual: location: /search/results.
Exception or Error
$ curl -si 'localhost:4000/search?q=x' | head -3
HTTP/1.1 302 Found
X-Powered-By: Express
location: /search/results
Your Environment
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI : 22.2.2
Angular : 22.2.2
Node.js : 24.18.0
Package Manager : npm 11.16.0
Operating System : linux x64
┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 22.2.2 │ ^22.2.2 │
│ @angular/cli │ 22.2.2 │ ^22.2.2 │
│ @angular/common │ 22.2.2 │ ^22.2.0 │
│ @angular/compiler │ 22.2.2 │ ^22.2.0 │
│ @angular/compiler-cli │ 22.2.2 │ ^22.2.0 │
│ @angular/core │ 22.2.2 │ ^22.2.0 │
│ @angular/forms │ 22.2.2 │ ^22.2.0 │
│ @angular/platform-browser │ 22.2.2 │ ^22.2.0 │
│ @angular/platform-server │ 22.2.2 │ ^22.2.0 │
│ @angular/router │ 22.2.2 │ ^22.2.0 │
│ @angular/ssr │ 22.2.2 │ ^22.2.2 │
│ rxjs │ 7.8.2 │ ~7.8.0 │
│ typescript │ 6.0.3 │ ~6.0.2 │
└───────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?
app.ts#L168-L176 builds Location from the stored redirectTo and never uses url.search. By then redirectTo has already been resolved to an absolute path, so whether it was relative is no longer known.
Router side: for a relative redirect, recognize.ts keeps only the segments of the new tree and continues with the original URL tree, so the query is kept. An absolute redirect throws AbsoluteRedirect(newTree), whose query comes from redirectTo only. Render-time redirects (guards, router.navigate) already keep the query (#31883).
I have a fix with tests and will open a PR for it.
Not browser specific. Seen with the default Express server.ts generated by ng new --ssr; the redirect comes from AngularNodeAppEngine.handle(), not from Express itself.
- Ngôn ngữ chính
- TypeScript
- Star
- 27k
- Fork
- 11.8k
- Merge trung bình
- 1 ngày 32 phút
- Pull request đã merge (30 ngày)
- 138
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của angular/angular-cli
-
area: @angular/cli
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
angular/angular-cli#34307 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Can't use an array of hostnames in --allowedHosts cli parameter in @angular/build:dev-serverĐang mởarea: @angular/build gemini-triaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
angular/angular-cli#33955 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area: @angular/cli gemini-triaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
angular/angular-cli#33055 · 1 bình luận · 3 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
SSR resolves relative `redirectTo` against the wrong base when the route path has several segmentsCó thể đã có người làm @bschaeublin đã nhận 3 ngày trước. Đang mởarea: @angular/ssr
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
angular/angular-cli#34300 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area: @angular/build
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
angular/angular-cli#34292 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của angular/angular-cli
Issue tương tự
-
bug help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
agent-task risk:low
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 88/100
guyellis/http-status-check#512 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
microsoft/playwright#43327 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
microsoft/TypeScript#64758 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
opensearch-project/OpenSearch-Dashboards#12937 ·
Maintainer thường phản hồi trong vòng 2 ngày