← 返回随写

2026/6/4

博客排错备忘录

对博客进行升级更新所遇到问题及解决方法

博客排错备忘录

本项目近期针对前台列表进行视觉升级(引入时光轴画廊/非对称错落流排版),并同步打通本地图片物理上传功能。由于涉及 Next.js App Router 编译机制与 Prisma 状态锁死,引发了页面未更新、接口报错等连锁反应。以下为优化路径、安全审计标准及全栈运维的底层解决方案。


一、 视觉与排版优化方案

1. 网页标签图标 (Favicon)

  • 规范:将 1:1 正方形图片通过在线工具转换为 32x3248x48 像素的 .ico 文件。
  • 部署:精准命名为 favicon.ico(全小写),物理拖入项目 app/ 根目录下进行覆盖,浏览器会自动识别。

2. 前台文章列表:时光轴画廊 / 非对称错落流

  • 首篇通栏:列表第一篇文章 (index === 0) 占据 md:col-span-2 全宽,放大标题与摘要建立视觉重心。
  • 错落双栏:后续文章自动切入桌面端双栏网格 (grid-cols-2)。背景衬托低调的大字重衬线数字编号 (font-serif opacity-5 text-7xl),营造实体杂志版面质感。
  • 微交互反馈:卡片悬停时触发平滑上浮 6px 并投射柔和阴影 (shadow-xl shadow-slate-200/40),封面图片同步执行微放大动画 (group-hover:scale-105 duration-500)。

3. 子元素溢出与滚动变色优化

  • 圆角刺破 Bug:最外层卡片底座拥有大圆角(如 rounded-[2rem]),内部白色表单或区域的直角背景因未受约束而溢出。
    • 解法:在最外层包裹容器上引入 overflow-hidden,利用控制边缘强行裁剪,使视觉弧度咬合。
  • 滚动闪白现象:页面向下滑动的一瞬间存在白色硬编码块闪烁。
    • 起因:系统高频监听滚动并触发 backdrop-blur(高斯模糊滤镜),浏览器高负载实时计算像素导致样式未渲染过渡(Flash of Unstyled Content)。
    • 解法:全面砍掉变色逻辑中的 backdrop-blur 相关类名。背景切换直接平滑演变为从完全透明(bg-transparent)向低调微灰(bg-[#f8f9fa]/90)的纯净透明度渐变,赋予硬件级平滑过渡属性 transition-all duration-500 ease-in-out

二、 后台本地图片物理上传与安全闭环

系统彻底抛弃远程 URL 文本框输入,重构为真实的本地二进制文件物理上传、服务端存储与 SQLite 路径映射。

1. 前端表单重构 (components/upload-form.jsx)

  • 本地物理预览:引入 React useEffect 配合浏览器原生 URL.createObjectURL(selectedImage) 机制。锁定文件后,无延迟挂载全屏绝对定位最高层级视图 (absolute inset-0 z-30 rounded-2xl overflow-hidden) 展现画面,并做好 URL.revokeObjectURL 销毁处理防止内存泄漏。
  • 事件冒泡阻断:在反悔删除按钮( 图标)上,必须硬编码绑定 e.preventDefault()e.stopPropagation()。切断原生事件向外层虚线框冒泡,解决点击删除却死循环弹出系统文件选择框的故障。
  • 前端第一道拦截网:在文件选定的临界点即时校验。文档不满足 .md 后缀或超过 1MB 予以阻断;图片不满足 JPG/PNG/WEBP 格式或超过 2MB 予以阻断。

2. 后端 API 路由重构 (app/api/admin/posts/upload/route.js)

  • 安全鉴权校验:接口顶部严格调用 getServerSession(authOptions) 进行会话审查。未授权、跨域或匿名的伪造包请求一律抛出 401 Unauthorized 强行熔断。
  • 服务端二次审计:在服务端核心层对接收到的 FormData 实施体积与 Mime-Type 强校验,防止恶意绕过前端验证。
  • 沙箱隔离存储:为防御路径遍历与木马文件注入攻击,彻底抹除原始文件名。调用随机 UUID 动态生成安全文件名 (crypto.randomUUID() + ext),利用 fs 模块写入磁盘 public/uploads/ 物理目录,随后将网络相对访问路径(/uploads/secure_name.jpg)落盘存入数据库的 coverImage 字段。

三、 全栈发布流水线排错与破防大招

现象:修改完代码并执行 git pull 后,线上前后台不论如何刷新、重启,网页都顽固地不发生任何变化。 本质:Next.js 在生产环境中拥有极其顽固的静态页面强缓存机制(SSG/ISR),以及 Prisma 客户端内存死锁。

1. 破除首页静态强缓存

在负责实时更新的前台主页(app/page.jsx)和列表页(app/musings/page.jsx)的最顶部(所有 import 之前),必须硬编码加上 Next.js 终极动态路由标头:

export const dynamic = 'force-dynamic'
该标头将强制终止打包器将其编译为冷冰冰的静态 index.html 缓存,迫使每次请求都进行实时的全栈计算与最新排版输出。

2. 破除 Unknown argument 'coverImage' 报错
该报错属于典型的 Prisma 骨架未对齐。当 prisma/schema.prisma 新增了 coverImage String? 字段后,必须在线上生成变动图纸并应用,否则 SQLite 数据库不会长出图片路径列,引发运行时异常。

👑 线上环境全栈编译一键清缓存命令
当代码成功 git pull 到服务器后,切勿只点击运维面板上的重启按钮。必须直接进入云服务器项目根目录终端,全选并执行以下这一整行复合指令:

Bash
npx prisma generate && npx prisma migrate deploy && rm -rf .next && npm run build
复合脚本执行步骤拆解:
npx prisma generate:在服务端内存中重新生成 Prisma 最新的客户端骨架类。

npx prisma migrate deploy:在完全不破坏、不删除线上已有老文章数据的前提下,自动安全地在物理 SQLite 中升级新字段。

rm -rf .next(核心防线):从物理层彻底粉碎上一次编译留下的所有旧包缓存、以及被误编锁死的静态 HTML 强缓存文件。

npm run build:调用 next build 引擎,将最新重构的 force-dynamic 与圆角裁剪等代码高干净度地重新编译打包。

后续动作:终端成功输出 ✓ Compiled successfully 后,在 1Panel 面板点击重启项目进程。随后,通过电脑键盘快捷键 Ctrl + Shift + N 开启完全隔离的浏览器无痕模式/隐身窗口(彻底绕过客户端浏览器的 JS 强缓存)访问网站,全新全栈重构后的前后台功能即会强制生效。