MEAN栈中Angular组件请求图片资源返回404 Not Found问题排查
问题原因定位
你遇到的404错误本质是静态资源的访问路径配置和数据库中存储的图片地址路径不匹配,和上传逻辑、MongoDB存储逻辑无关,问题出在Express静态托管的路径映射规则上:
- 你在
server.js中配置的静态托管规则为:
这段代码的实际效果是:Express会把项目下的app.use(express.static(path.join(__dirname, 'public')));public目录作为静态资源根目录,也就是说public文件夹里的所有文件,对外暴露的访问路径是从根路径开始计算的。比如存在public/image-1617990660620.png的文件,实际可以通过http://localhost:3000/image-1617990660620.png直接访问,根本不会匹配/public/xxx的请求路径。 - 你在图片上传接口中,拼接存到MongoDB的图片地址时,人为多加了
public/前缀:
这就导致Angular端拿到这个地址发起请求时,请求的是const avatar = 'http://localhost:3000/public/' + req.file.filename;http://localhost:3000/public/xxx.png,Express没有对应的路由匹配这个路径,自然返回404。
对应解决方法
你可以根据自己的需求二选一即可:
方案1:匹配现有静态托管规则(改动小)
修改上传接口中拼接avatar字段的代码,去掉多余的public/前缀:
// 修改前 const avatar = 'http://localhost:3000/public/' + req.file.filename; // 修改后 const avatar = 'http://localhost:3000/' + req.file.filename;
注意:之前已经存到MongoDB的旧图片记录,其avatar字段依然带public/前缀,需要手动批量修正数据库中的旧值,才能正常加载。
方案2:匹配现有数据库存储的路径(兼容旧数据)
修改server.js中的静态托管配置,给静态资源的访问加上/public前缀,让访问路径和你存的地址完全对齐:
// 修改前 app.use(express.static(path.join(__dirname, 'public'))); // 修改后 app.use('/public', express.static(path.join(__dirname, 'public')));
配置完成后,public目录下的所有文件,对外的访问路径就会变成http://localhost:3000/public/xxx.png,和你数据库里存的地址完全匹配,不需要改动旧数据。
额外的潜在问题提醒
你在Multer的存储配置中,写的文件保存路径是相对路径:
destination: (req, file, cb) => { cb(null, 'public'); }
这个写法的风险是:如果启动Node服务的工作目录不是项目根目录,上传的文件会被存到错误的位置。建议改成绝对路径写法,避免后续部署时出问题:
// 因为这段代码在routes文件夹下,需要向上跳转一层定位到项目根目录的public文件夹 destination: (req, file, cb) => { cb(null, path.join(__dirname, '../public')); }
内容的提问来源于stack exchange,提问作者Mohid
相关产品推荐
相关产品推荐

