feat(C-01):路由/代理前缀冲突修复
SPA冲突路由改名+旧路径Navigate重定向(/api-docs→/open-api-docs、/api-detail→/open-api-detail、/article→/post、/user→/user-home);vite代理宽前缀改精确正则白名单;nginx.conf同步同口径;新增86路由回归脚本+Playwright 3项(86/86全绿)。
This commit is contained in:
+179
-2
@@ -25,8 +25,11 @@ server {
|
||||
}
|
||||
|
||||
# API 反代 → Granian(ADRF 异步视图)
|
||||
# 路由分散在 /api /user /bug /article /chat /learn /message /tool /history /media 等前缀下
|
||||
location ~ ^/(api|user|bug|article|chat|learn|message|tool|history|media|search|app|logs|s|air-quality|weather|currency|shorturl)/ {
|
||||
# C-01:精确收窄到后端真实存在的 API 前缀。SPA 路由(/open-api*、/post/*、
|
||||
# /user-home*、/articles、/learn 列表页等)一律落到下面的 `location /` 回退,
|
||||
# 不再被宽正则劫持。旧分享链接(/article/:id、/user/:id、/api-detail/* 等)
|
||||
# 由前端 SPA 内 <Navigate> 重定向承接,nginx 直接放行到 index.html 即可。
|
||||
location ~ ^/api/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
@@ -39,6 +42,165 @@ server {
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 user.urls(/user/<action>/):SPA 已迁到 /user-home*,旧 /user/:id 分享
|
||||
# 链接由前端重定向承接;数字 id 形态放行到 SPA,其余代理到后端
|
||||
location ~ ^/user/\d+/?$ {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
location ~ ^/user/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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 Content-Type $http_content_type;
|
||||
proxy_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 bug.urls 仅 /bug/reports/*;SPA /bug 与 /bug-detail 放行
|
||||
location ~ ^/bug/reports/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 article.urls 仅 articles|my-articles|comments;SPA /post/*、/articles 放行
|
||||
location ~ ^/article/(articles|my-articles|comments)/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 learn.urls 子段;SPA /learn 列表页放行
|
||||
location ~ ^/learn/(courses|chapters|my-courses|my-progress|materials|favorites|cdn)/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 message.urls(/message/*);SPA /messages(多 s)天然不命中
|
||||
location ~ ^/message/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 chat.urls 子段;SPA /chat 本体放行
|
||||
location ~ ^/chat/(friend-requests|friends|users|conversations|messages|upload|favorite-stickers)/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 tool.urls(/tool/*);SPA /tool-detail 放行(不以 /tool/ 开头)
|
||||
location ~ ^/tool/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 history.urls 仅 records/;SPA /history 列表页放行
|
||||
location ~ ^/history/records/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 后端 search 查询串形态(GET /search/?q=);裸 /search(页)与无参 /search/ 放行到 SPA。
|
||||
# location 按 URI 匹配、看不见 query string,故用 $args 分流。
|
||||
location = /search/ {
|
||||
error_page 418 = @spa_fallback;
|
||||
if ($args = "") { return 418; }
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
}
|
||||
location ~ ^/search/(suggestions|hot-keywords)/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
}
|
||||
|
||||
# 后端 app(changelog)/ logs / shorturl
|
||||
location ~ ^/(app|logs/api|shorturl)/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
# 短链跳转 /s/<code>/:仅短码形态代理,其余(/settings、/shorturl-detail)放行
|
||||
location ~ ^/s/[^/]+/?$ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
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_read_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
}
|
||||
|
||||
# Django admin / swagger / redoc / i18n / 测试页
|
||||
location /admin/ { proxy_pass http://backend:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 50M; }
|
||||
location /swagger { proxy_pass http://backend:8000; proxy_set_header Host $host; }
|
||||
@@ -66,8 +228,23 @@ server {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
}
|
||||
|
||||
# C-05 SEO 预渲染优先:蜘蛛/首屏直接拿到含正文的静态 HTML,
|
||||
# React hydrate 后照常接管交互(预渲染页内含 location.replace 跳转到 SPA 路由)。
|
||||
# 首页用 index.seo.html(不覆盖 SPA 外壳 index.html);工具页/聚合页为目录 index.html。
|
||||
location = / {
|
||||
try_files /index.seo.html /index.html;
|
||||
}
|
||||
location ~ ^/(utility/[a-z-]+|qrcode-generator|color-picker|baidu-translate|utility|top)/?$ {
|
||||
try_files $uri $uri/index.html $uri/ /index.html;
|
||||
add_header Cache-Control "public, max-age=3600";
|
||||
}
|
||||
|
||||
# SPA 路由回退(放在最后,避免拦截上面的 API 请求)
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location @spa_fallback {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user