开发正常上线404是因为构建后css与图片路径分离导致相对url解析错误;应将图片放public目录并用绝对路径引用,或通过js导入实现哈希和路径自动处理。

为什么开发正常、上线就404
根本不是图片丢了,是浏览器按 CSS 文件最终位置去拼 URL,而构建后 CSS 和图片被分到不同目录。比如构建后 CSS 在 /assets/css/app.css,图片在 /assets/img/bg.png,但 CSS 里写的是 url("../img/bg.png"),浏览器就会去请求 /assets/css/../img/bg.png → /assets/img/bg.png —— 看似对,可一旦 CSS 被抽到 /css/app.css(没带 assets),路径就变成 /css/../img/bg.png → /img/bg.png,而实际图片其实在 /assets/img/bg.png。
常见错误现象:
- 本地
vite dev正常,vite build后背景图全 404 - Network 面板看到请求地址是
https://example.com/img/bg.png,但实际资源在/assets/img/bg.png - SCSS 里写
url('@/assets/bg.png'),编译后原样输出,浏览器直接报错
用 public/ 目录 + 根路径最稳
适合 logo、banner、favicon 这类不需哈希、不常变动的资源。构建工具完全不处理它,路径绝对可控。
实操建议:
- 把图片放进项目根目录下的
public/assets/bg.png - CSS 或 SCSS 中直接写
background-image: url('/assets/bg.png');(开头必须有/) - 确认
vite.config.ts中base配置匹配部署路径:比如部署在子路径/my-app/,就要设base: '/my-app/',这样最终 URL 就是https://example.com/my-app/assets/bg.png - Vue CLI 项目同理,确保
process.env.PUBLIC_URL注入正确,并在 CSS 中用url('/assets/bg.png')
需要哈希或动态切换?改用 JS 导入
当图片要压缩、加 hash、按主题切换、或和组件逻辑强绑定时,CSS 的 url() 就不合适了——它只是字符串,构建工具默认不解析。
实操建议:
- 在组件中
import bg from '@/assets/bg.png' - Vue:
:style="{ backgroundImage: `url(${bg})` }" - React:
style={{ backgroundImage: `url(${bg})` }} - 这样
bg是真实模块路径,构建后自动变成/assets/bg.8a1f2e.png,带 hash、压缩、路径重写全由打包器接管 - 全局 mixin 里不能
import?那就把路径作为参数传入,由调用方传已import的变量
别踩这些“看似能跑”的坑
很多写法本地能过,上线立刻挂,因为它们依赖未声明的构建行为或环境假设。
容易出错的写法:
-
url(./assets/bg.png):构建后 CSS 被抽离,.基准变成dist/css/,不再是源码结构 -
url('~@/assets/bg.png'):Webpack 旧版 hack,Vite 不支持,Vue CLI 5+ 已弃用 -
url(/static/bg.png):Django 里必须确保STATIC_URL = '/static/',且 Nginx/Apache 配置了/static/路径代理 - 在
<style></style>标签里写背景图:容易漏掉构建时的路径重写逻辑,尤其用了MiniCssExtractPlugin
真正容易被忽略的是:SCSS/Sass 本身没有资源处理能力,url() 里的内容只是字符串;构建工具是否重写它,取决于 loader 是否识别并拦截——而默认情况下,它不会。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











