404.html必须严格小写、置于根目录、无路径前缀,且服务器须返回真实404状态码;HTML需含语义化404文字、UTF-8无BOM编码、内联CSS、可访问结构,并禁用前端模拟。

404.html 文件必须严格小写、放根目录、不带任何路径前缀
GitHub Pages、Netlify、Vercel、Cloudflare Pages 这些平台只认 404.html 这个确切文件名,且必须位于 Git 仓库或构建输出的最顶层目录。写成 404.htm、error404.html、pages/404.html 或 404.HTML 都不会被接管。
常见踩坑点:
- Windows 记事本保存时可能悄悄加 BOM 头,导致部署后页面空白或状态码失效;建议用 VS Code 等编辑器并确认编码为 UTF-8 without BOM
- Jekyll 用户需在
404.html开头加---\npermalink: /404.html\npublished: false\n---,否则会被当作普通文章渲染 - macOS 本地测试不区分大小写,但 Linux 服务器会严格校验 —— 提交前用
git ls-files | grep 404确认文件名是纯小写
服务器必须返回真实 404 HTTP 状态码,不能靠前端“模拟”
浏览器地址栏显示 /xxx 但 Network 面板里 Status 是 200 OK?那根本不是 404 页面。搜索引擎会把它当正常页面收录,用户刷新也得不到重试提示。
验证方式只有两个:
-
curl -I https://yoursite.com/nonexistent-path,第一行必须是HTTP/1.1 404 Not Found - Chrome DevTools → Network → 访问一个明显不存在的路径(如
/xyz-abc)→ 看该请求的 Response Headers 中Status字段
不同环境配置要点:
- 静态托管(GitHub Pages):自动支持,但仅限根目录
404.html;Netlify 需在_redirects写/* /404.html 404 - Nginx:在
server块中加error_page 404 /404.html;,并确保location = /404.html存在且未被try_files规则覆盖 - Express:必须显式调用
res.status(404).sendFile(path.join(__dirname, '404.html')),不能只res.sendFile() - SPA(React/Vue):路由 fallback 规则如
try_files $uri $uri/ /index.html会吞掉所有 404,必须排除/404.html路径
HTML 结构必须语义化, 里得有 “404” 文字
不是装饰,是搜索引擎和屏幕阅读器识别错误页的唯一可靠信号。用 SVG、CSS 伪元素、JS 动态插入 “404”,视障用户听不到,爬虫读不到。
底线结构示例(无 JS、无外部依赖):
<meta charset="UTF-8"><title>404 - 页面未找到</title><meta name="robots" content="noindex"><style>
body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
main { text-align: center; max-width: 600px; padding: 0 20px; }
h1 { font-size: clamp(2.5rem, 5vw, 4rem); margin: 0 0 1rem; }
p { color: #666; line-height: 1.6; }
a { color: #007bff; text-decoration: none; font-weight: 500; }
</style><main role="main"><h1>404 Not Found</h1>
<p>抱歉,您访问的页面不存在。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20d3191a227.jpg" alt="DeepBI DHTML 页面生成器" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器" class="overflowclass">DeepBI DHTML 页面生成器</a>
<p class="overflowclass">生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力:
- 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面;
- 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”;
- 提及位于 `apps/console/src/featur</p>
</div>
<a rel="nofollow" href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p><a href="/">← 返回首页</a></p>
</main>
关键点:
-
必须含 “404”,否则搜索结果点进来像进了首页 -
包裹核心内容,让屏幕阅读器跳过导航直读错误信息 - CSS 必须内联,
里控制在 1KB 以内;禁用 - 所有文字与背景对比度 ≥ 4.5:1(可用 webaim.org/contrastchecker 验证)
带搜索框的 404 页面,别用 JS 拦截表单提交
所谓“站内搜索”,只是把用户输入转发给 /search?q=xxx,不是在 404 页面里查数据库。加 JS 拦截、fetch、history.pushState 反而会让跳转失败、SEO 不友好、JS 禁用时直接失灵。
正确做法:
- 用标准
,input 必须带name="q"(或你后端约定的参数名) - 不要写
onsubmit="return false"或event.preventDefault()—— 这会让表单完全不可用 - 给 input 加
autofocus,回车默认触发表单提交;避免type="search"(Safari 多出 × 按钮,样式干扰大) - 搜索框位置放在错误说明下方、返回首页链接上方,视觉流是:错误 → 解决入口 → 备选路径
如果站点搜索页实际路径是 /blog/search,action 就得写完整,不能只写 search —— 这是最常被忽略的硬编码陷阱。
真正难的不是写 HTML,而是让服务器每次对不存在路径都精准返回这个文件 + 404 状态码。哪怕结构再规范,只要状态码不对,就等于没做。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










