404页面必须是纯HTML静态文件,内联CSS和必要JS,由服务器返回真实404状态码;禁止JS渲染、前端路由伪造或重定向,需包含明确提示、可点击出口及当前URL展示,确保弱网可用、路径正确、SEO合规。

404页面必须用HTML静态文件,不能依赖JavaScript渲染
服务端返回404状态码时,浏览器会直接加载你配置的404.html(或类似路径),此时页面尚未执行JS,fetch、React、Vue.mount() 全部无效。所以404页面得是纯HTML + 内联CSS + 内联少量必要JS(仅用于交互增强,非核心内容)。
常见错误:用create-react-app构建出的build/404.html里只放了个空div#root,结果JS加载失败或路由没匹配,用户看到白屏——这不是404页,这是故障现场。
- 所有文字、按钮、返回链接必须写死在HTML里,不可通过
document.write或innerHTML注入 - CSS建议内联在
<style></style>中,避免额外HTTP请求失败导致样式丢失 - 如果要用JS(比如“复制当前URL”按钮),确保
try/catch包裹,且不影响主内容显示
HTTP状态码必须为404,不能靠前端路由伪造
很多开发者在vue-router或react-router里配个* → <notfound></notfound>组件,但服务器实际返回的是200 OK。搜索引擎和爬虫看到200,会把错误路径当有效页面收录,损害SEO;用户刷新后也可能丢失路由上下文。
真正有效的404页,前提是Web服务器(Nginx/Apache/Vercel/Cloudflare Pages)明确返回HTTP/1.1 404 Not Found响应头。
立即学习“前端免费学习笔记(深入)”;
- Nginx示例:
error_page 404 /404.html;,并确保location = /404.html块里没有return 200 - Vercel:在
vercel.json中配置"rewrites": [{ "source": "/(.*)", "destination": "/404.html" }]不行——这会覆盖所有路径并返回200;正确做法是不配rewrite,靠404.html文件名自动触发 - 本地测试时,用
npx serve -s起服务,它会自动识别404.html;但python3 -m http.server不会,需换工具
页面内容要包含用户能立刻行动的关键信息
404不是设计秀场。用户此刻的诉求很明确:我点错了?链接过期了?还是网站崩了?页面得在1秒内给出答案。
别写“抱歉,您访问的页面不存在”,这是废话。直接告诉用户:这是什么、不是什么、下一步做什么。
- 顶部大字写明
404 Not Found(带状态码,方便用户截图反馈) - 第二行简短解释:
这个地址没有对应的内容,可能已被删除或从未存在过 - 提供3个以内可点击的真实出口:
返回首页、查看最新文章、搜索站内内容(搜索框action指向/search,不依赖JS) - 底部加一行小字:
当前URL:<span id="url-display"></span>,用内联JS填充(document.getElementById('url-display').textContent = window.location.href),方便用户核对或反馈
兼容性与性能细节容易被忽略
404页常被当成边缘场景,但它是用户首次接触你网站失败时的最后印象。几个硬伤会直接放大挫败感:
- 图片用
<img src="/logo.svg" alt="Logo">而非相对路径./logo.svg——404路径可能是/posts/2023/foo/bar,相对路径会拼成/posts/2023/foo/logo.svg404连环套 - 字体不要引用Google Fonts等外部CDN,内联一个系统字体栈:
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - 整个HTML文件控制在10KB以内(gzip后),确保弱网下也能秒开;删掉所有注释、空格、无用meta
- 不要自动跳转(
<meta http-equiv="refresh">或setTimeout(location.href=...)),干扰用户判断,还可能引发双跳问题
最麻烦的其实是路径引用和服务器配置的耦合——同一个404.html,在Vercel上工作,在Nginx上404图片全挂,往往是因为base href没关或路径前缀没处理。动手前先确认你的部署目标如何解析静态资源路径。



















