Skip to content

fix(proxy): 非 ASCII docs 路径 edge 直接 404,避免 x-next-cache-tags 500#371

Merged
longsizhuo merged 3 commits into
mainfrom
fix/docs-non-ascii-404
Jul 18, 2026
Merged

fix(proxy): 非 ASCII docs 路径 edge 直接 404,避免 x-next-cache-tags 500#371
longsizhuo merged 3 commits into
mainfrom
fix/docs-non-ascii-404

Conversation

@longsizhuo

Copy link
Copy Markdown
Member

问题

Closes #370 / Sentry INVOLUTIONHELL-FRONTEND-4(197 次)

爬虫访问不存在的中文 docs 路径(如 .../你的图片.jpg "自定义鼠标悬停显示名",AhrefsBot 把文档里反引号包的示例代码当链接爬)→ 未知 slug 走运行时动态渲染 → Vercel 把中文写进 x-next-cache-tags 响应头 → Node 拒绝 >0xFF header 字符 → 未捕获 TypeError → 500。

上游 vercel/next.js#92145 因缺复现被关(未修),升级 16.2.10 无效;页面内拦不住(崩溃发生在 notFound() 返回之后的框架层 header 写入)。

方案

proxy.ts(edge)把「解码后仍含 >0xFF 字符的 docs 路径」直接裸 404:

  1. matcher:dot-path 排除组新增 docs 例外(对齐既有 leetcode 例外)——崩溃 URL 带 .jpg,不放开根本进不了 middleware。public/ 下没有任何 /docs/... 路径的静态资源,安全。
  2. lib/poisoned-docs-path.ts:守卫函数(独立模块是为了 vitest 可测,proxy.ts 引 next-intl 在 node 环境 import 不动)。
  3. 顺序:bot-scan 404 → leetcode slug-map 301 → 本守卫 404 → next-intl。中文 leetcode 旧 URL 先被 301 到拼音页,轮不到守卫。

为什么不会误伤

  • content/docs/ 非 ASCII 文件名只在 leetcode 目录,其 canonical URL 全是拼音(slug-map 68 个目标 0 非 ASCII)
  • 后端 doc_paths 499 行历史路径实测 SQL:非 leetcode 的非 ASCII 行 = 0
  • ASCII 未知路径(含 [object Object] 这类垃圾)仍走 page.tsx 的 resolve→301/404 流程,行为不变

验证

  • pnpm test 67 通过(新增 15 用例:守卫函数 + matcher 不变量,含 PR 🔥 hotfix(proxy): matcher 排除 oauth/auth/analytics,修复登录 404 #335 oauth 排除回归)
  • pnpm typecheck / pnpm lint(0 error)
  • pnpm dev curl 矩阵:中文垃圾路径 404 裸响应 / 正常 docs 页 200 / 旧中文 leetcode URL 301 到拼音 / /oauth/render/github 不被加 locale 前缀 / ASCII 垃圾路径走 resolve 404
  • pnpm build 通过,/[locale]/docs/[...slug] 仍为 ● SSG

附带收益:这类垃圾请求不再进 Fluid lambda、不再打后端 resolve 接口。

Fixes INVOLUTIONHELL-FRONTEND-4

🤖 Generated with Claude Code

https://claude.ai/code/session_01RtSNVtrEkCsFVHrbt4Zjgi

爬虫构造的不存在中文 docs 路径(如 ".../你的图片.jpg \"悬停名\"")会进
[...slug] 的运行时动态渲染,Vercel 把中文写进 x-next-cache-tags 响应头,
Node 拒绝 >0xFF 的 header 字符 → 未捕获 TypeError → 500。上游
vercel/next.js#92145 未修,页面内拦不住(崩溃在 notFound() 之后的框架层)。

- matcher 的 dot-path 排除新增 docs 例外(对齐 leetcode 例外),让带点的
  垃圾路径能进 middleware;/docs/ URL 下无真实静态资源,放开安全
- 新增 isPoisonedDocsPath:解码后仍含 >0xFF 字符的 docs 路径返回裸 404。
  合法 docs slug 全 ASCII(中文 leetcode 旧 URL 由 slug-map 先行 301,
  doc_paths 历史表无非 leetcode 中文行),不误伤 resolve 重定向
- ASCII 未知路径仍走 page.tsx 的 resolve→301/404 流程,行为不变

Fixes INVOLUTIONHELL-FRONTEND-4
Closes #370

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtSNVtrEkCsFVHrbt4Zjgi
Copilot AI review requested due to automatic review settings July 18, 2026 21:31
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
involutionhell-github-io Ready Ready Preview, Comment Jul 18, 2026 10:46pm
website-preview Ready Ready Preview, Comment Jul 18, 2026 10:46pm

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread lib/poisoned-docs-path.ts Fixed
github-actions Bot and others added 2 commits July 18, 2026 22:28
Co-authored-by: github-code-quality[bot] <github-code-quality[bot]@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtSNVtrEkCsFVHrbt4Zjgi
@longsizhuo
longsizhuo merged commit 82ed58d into main Jul 18, 2026
7 of 9 checks passed
@longsizhuo
longsizhuo deleted the fix/docs-non-ascii-404 branch July 18, 2026 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: 未知非 ASCII 路径在 Vercel 上 500(x-next-cache-tags 头崩溃),应为干净 404

2 participants