404错误应通过Network面板标红请求的Request URL精准定位,而非猜测;需比对浏览器实际请求路径与服务器真实文件路径,检查大小写、编码、base标签、构建工具配置及服务器静态资源路由规则。

看 Network 面板里标红的请求路径
404 错误不是猜出来的,是浏览器 Network 面板里标红的那条请求告诉你的。打开 F12 → 切到 Network → 刷新页面 → 找状态码为 404 的请求项,点开它,在 Headers 标签页里看 Request URL 字段。
这个 URL 就是浏览器实际发出去的地址,也是你必须对齐的目标。常见偏差包括:
-
Request URL是http://localhost/css/style.css,但文件实际在assets/css/style.css—— 那就要改 HTML 里的<link href="assets/css/style.css"> -
Request URL是http://localhost/static/js/app.js,而你把 JS 放在了项目根目录 —— 说明构建工具(如 Vite、CRA)默认启用了/static/前缀,不能手动删掉 - URL 中出现
%C3%B6这类编码,但文件名是未编码的fooö.html—— Linux/macOS 服务器不会自动解码,建议资源名全用 ASCII
确认你是走 HTTP 服务,不是 file://
双击 HTML 文件打开,地址栏显示 file:///Users/xxx/index.html,这种压根不经过服务器,也不会返回 404 状态码。它出问题只会报 Not allowed to load local resource 或空白页。
真要测 404,必须走 HTTP 协议:
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- Python 用户:
python -m http.server 8000,然后访问http://localhost:8000/index.html - Node.js 用户:
npx serve -s(推荐),或npx http-server -p 5000 - Vite 项目:
npm run build && npm run preview,别只用npm run dev测静态资源路径 - VS Code Live Server 插件启动后,务必用它右下角弹出的链接,别拖 HTML 到浏览器
检查服务器是否暴露了那个路径
很多框架(Django、Flask、Spring Boot、Next.js)默认不把整个项目目录当 Web 根目录,而是只开放特定子目录下的静态文件。
例如:
- Django:图片必须放
static/images/logo.png,写成<img src="images/logo.png">就 404 —— 因为 Django 只服务/static/下的文件,且模板中要用{% static 'images/logo.png' %} - Spring Boot:静态资源默认从
classpath:/static/或classpath:/public/提供,src/main/resources/static/css/main.css对应http://localhost/css/main.css - GitHub Pages:自定义 404 页面必须叫
404.html,且放在仓库根目录;任何子目录下的404.html都无效
注意大小写、隐藏扩展名和 base 标签
Windows 上双击保存的 index.html,可能实际是 index.html.txt;Linux/macOS 服务器对大小写敏感,About.html 和 about.html 是两个文件。
另外,<base href="/admin/"> 会改变所有相对路径的解析基准:
- 当前页面 URL 是
http://localhost/admin/user,<script src="app.js">实际请求的是http://localhost/admin/app.js,不是http://localhost/app.js - Vite 项目设了
base: "/subapp/",但 HTML 没写<base>,或写了但没加结尾斜杠,都会导致资源加载失败 - 多数现代构建工具不需要手写
<base>,除非你明确部署在子路径下
真正卡住人的,往往不是路径写错,而是你以为路径对了,其实服务器根本没被配置成能提供那个路径——比如 Nginx 的 location /assets/ 块漏写了,或者 Spring Boot 的拦截器把 /swagger-ui.html 拦截了却没放行静态资源。先确认请求发到了哪儿,再确认那个“哪儿”有没有权限吐出你要的东西。


















