Vue+Node+Nginx博客项目上线全流程踩坑记录(图片404、权限报错、混合内容、不安全锁、后端常驻)

前言

本次部署个人博客前后端项目,全程遇到了静态图片404、文件权限拒绝、头像上传500报错、HTTPS混合内容、浏览器地址栏不安全、后端终端关闭即停止运行等一系列线上经典问题。本文完整记录所有报错现象、根因分析、终极解决方案,一站式避坑,适合前后端分离项目云服务器部署参考。

项目架构:Vue3前端 + Express后端 + Nginx反向代理 + SSL证书HTTPS + PM2进程守护

一、问题1:后端上传图片404,静态资源无法访问

1.1 问题现象

前端上传头像成功提示,但图片地址访问404,地址为 http://域名/uploads/xxx\.jpg,服务器资源找不到对应文件。

1.2 排查过程

1、后端已配置express静态资源目录,代码无语法错误;
2、重启服务后问题依旧;
3、服务器执行 ls \-l 对应图片路径,提示 No such file or directory

1.3 根因

数据库缓存了旧的图片路径,但是服务器本地真实图片文件已丢失,属于数据与文件资源不匹配。

1.4 解决方案

1、清空无效的旧图片路径缓存;
2、前端重新上传头像,生成全新的本地图片文件;
3、确保Express静态资源配置使用服务器绝对路径(避免相对路径出错)。

// app.js 最终正确静态资源配置
const path = require('path');
app.use('/uploads', express.static('/www/wwwroot/backend/uploads'));

二、问题2:头像上传接口500报错 EACCES 权限不足

2.1 问题现象

重新上传头像时报500服务器错误,后端日志报错:EACCES: permission denied, open \&\#39;/www/wwwroot/backend/uploads/xxx\.jpg\&\#39;,无法写入图片文件。

2.2 根因

uploads文件夹权限、所属用户不对,Node进程(admin用户)没有文件写入权限,导致multer无法保存上传的图片。

2.3 终极修复命令

# 修改文件夹所属用户为运行后端的admin
sudo chown -R admin:admin /www/wwwroot/backend/uploads
# 赋予读写执行权限
sudo chmod -R 755 /www/wwwroot/backend/uploads

执行后查看权限,确认 drwxr\-xr\-x admin admin 权限正常,重启后端即可正常上传。

三、问题3:页面存在混合内容,HTTPS网站加载HTTP资源

3.1 问题现象

服务器已配置SSL证书、全站HTTPS,但是浏览器控制台提示混合内容警告,头像资源被拦截。

3.2 根因

后端上传接口返回的图片地址为本地localhost HTTP地址http://localhost:5000/uploads/xxx\.jpg
HTTPS页面加载HTTP资源,浏览器安全策略直接拦截,同时埋下“网站不安全”隐患。

3.3 解决方案

修改后端头像上传逻辑,不再返回相对路径/localhost路径,直接返回完整HTTPS域名路径

// 错误写法(开发环境遗留问题)
const avatarUrl = `/uploads/${filename}`;
const avatarUrl = `http://localhost:5000/uploads/${filename}`;

// 生产环境正确写法
const avatarUrl = `https://zhiguxiaoyao.hyx20.cn/uploads/${filename}`;

四、问题4:全站配置HTTPS、HSTS后,浏览器仍显示“不安全”

4.1 问题现象

已完成:80端口强制跳转443、SSL证书正常、HSTS强制HTTPS、所有资源均为HTTPS请求、控制台无任何报错,但浏览器地址栏依旧显示“不安全”。

4.2 关键验证(证明服务端100%无问题)

服务器执行 curl \-I https://域名,正常返回:

  • SSL certificate verify ok:证书合法有效

  • strict-transport-security:HSTS强制HTTPS已生效

  • 协议为TLSv1.3、HTTP/2,安全协议拉满

4.3 核心根因(90%上线新手踩坑)

浏览器安全缓存标记机制
域名曾经存在HTTP混合内容、不安全资源,浏览器会永久缓存该域名的不安全标记,即使后续所有问题修复,普通浏览器窗口也不会立刻恢复绿色锁。

4.4 验证&解决方式

1、无痕/隐私模式访问网站:直接显示绿色安全锁(证明项目完全安全)
2、普通窗口解决:清除浏览器全部缓存+Cookie(所有时间),重启浏览器即可恢复安全标记

五、问题5:后端node服务关闭终端即停止,无法常驻运行

5.1 问题现象

使用 node server\.js 启动后端,关闭SSH终端、断开连接后,服务直接停止,网站无法访问。

5.2 解决方案:PM2进程守护(永久后台运行+开机自启)

1、基础启动(单进程,避免端口冲突)
# 关闭所有重复进程
pm2 delete all
# 启动唯一后端服务
pm2 start server.js --name="blog-backend"
2、配置开机自启(永久生效)
pm2 save
pm2 startup
3、常用PM2运维命令
pm2 status   # 查看服务运行状态
pm2 restart blog-backend  # 重启后端
pm2 logs blog-backend     # 查看后端报错日志

5.3 避坑重点

禁止多进程同名启动,会导致端口抢占、接口报错、上传异常,保持单进程常驻即可。

六、补充:正常安全域名对比参考

同服务器下另一项目 langchain\.hyx20\.cn 配置完全一致,全程无不安全提示,印证结论:服务端配置无任何问题,唯一区别是该域名无历史不安全缓存

七、最终项目上线标准配置(无坑版)

1、Nginx核心安全配置

  • 80端口永久301重定向HTTPS

  • 开启TLS1.2/TLS1.3、HTTP2协议

  • 配置HSTS长期强制HTTPS

  • 静态资源、uploads文件反向代理正常

2、后端核心配置

  • 静态资源使用服务器绝对路径

  • 上传接口返回完整HTTPS域名地址

  • uploads目录权限755、所属用户正确

  • PM2常驻进程、开机自启、崩溃自动重启

八、全网最全避坑总结

  1. 图片404优先查文件是否真实存在,不是查代码,数据库旧路径缓存是高频坑点;

  2. 上传500报错99%是权限问题,优先改目录所属用户和权限;

  3. 混合内容根源是后端返回localhost/HTTP地址,必须统一返回HTTPS域名;

  4. 浏览器“不安全”不一定是项目问题,无痕模式验证是最准的判断方式;

  5. Node项目上线必须用PM2,杜绝终端关闭服务停止,禁止多进程冲突;

  6. 所有线上环境,禁止出现 localhost、127\.0\.0\.1 对外暴露路径。

九、最终上线状态

✅ SSL证书正常、HTTPS绿色安全锁(无痕模式秒出)
✅ 图片上传、展示完全正常,无404/500报错
✅ 无混合内容、无安全警告
✅ 后端永久后台运行、开机自启、稳定不宕机
✅ Nginx反向代理、路由、静态缓存全部生效

更多推荐