介绍如何在个人网站中实现简历 PDF 动态水印,包括 pdf-lib 处理、随机水印生成、Resume ID 追踪以及下载记录系统设计。
在个人网站中提供简历下载是很多开发者都会实现的功能。
但是,一个简单的 PDF 下载接口存在一个问题:
简历被下载之后,很难知道它来自哪里,也无法控制传播。
例如:
用户访问个人网站 │ ▼ 点击下载简历 │ ▼ 获得 resume.pdf
如果这份简历被转发到其他地方,我们无法知道:
因此,我在个人网站中加入了一套 PDF 动态水印系统。
它包含:
让每一次下载的简历都拥有唯一身份。
很多个人网站的简历下载都是直接返回静态文件:
return new Response(resume.pdf)
这种方式简单,但是存在几个问题。
所有用户下载的都是同一个 PDF。
如果文件传播出去:
resume.pdf
无法知道来源。
没有记录:
无法分析简历访问情况。
简历通常包含:
加入水印可以降低未经授权传播的概率。
整个系统流程如下:
用户 │ ▼ Resume Download API │ ├──────────────┐ ▼ ▼ 生成 Resume ID 记录下载日志 │ ▼ PDF Processing │ ▼ 添加动态水印 │ ▼ 返回 PDF
Node.js 中可以使用 pdf-lib 操作 PDF。
安装:
npm install pdf-lib
加载 PDF:
import { PDFDocument } from 'pdf-lib' const pdfDoc = await PDFDocument.load(buffer)
获取所有页面:
const pages = pdfDoc.getPages()
然后可以对每一页进行修改。
最简单的方式是在页面上绘制文字:
page.drawText('WEI HUIJIE', { x:100, y:400, size:20, opacity:0.15 })
但是固定位置存在问题:
WEI HUIJIE WEI HUIJIE
每一次下载都完全一样。
因此需要更加灵活的水印策略。
通过循环生成多个水印:
for(let x=-100;x<width;x+=180){ for(let y=-50;y<height;y+=120){ page.drawText( 'WEI HUIJIE', { x, y, size:16, opacity:0.12, rotate:degrees(-35) } ) } }
效果类似:
WEI HUIJIE WEI HUIJIE WEI HUIJIE WEI HUIJIE WEI HUIJIE
这样可以覆盖整个页面。
固定网格仍然存在一个问题:
每次下载的位置完全一样。
因此加入随机偏移:
const offsetX = Math.random()*100 const offsetY = Math.random()*100
生成:
for( let x=-100+offsetX; x<width; x+=180 )
每一次生成 PDF:
第一次下载: WEI HUIJIE WEI HUIJIE 第二次下载: WEI HUIJIE WEI HUIJIE
水印布局都会不同。
除了视觉水印,还需要一个唯一标识。
例如:
WEI HUIJIE Resume Code: A82kd91L https://www.weihuijie.com
生成短 ID:
import { nanoid } from 'nanoid' const resumeCode = nanoid(10)
相比 UUID:
550e8400-e29b-41d4-a716-446655440000
短 ID 更适合展示。
为了追踪下载行为,需要保存记录。
例如 Prisma:
model ResumeDownload { id String @id @default(cuid()) resumeCode String @unique ip String? userAgent String? referer String? createdAt DateTime @default(now()) }
每次下载:
生成 Resume Code │ ▼ 保存数据库 │ ▼ 生成 PDF 水印
完整流程:
GET /api/resume/download │ ▼ 生成 nanoid │ ▼ 创建 ResumeDownload │ ▼ 读取原始 PDF │ ▼ 添加水印 │ ▼ 返回 PDF
最终用户获得的不是固定文件,而是一份动态生成的简历。
对于个人网站,目前的方案已经足够。
但是未来可以继续扩展:
例如:
可以统计:
每日下载数量 热门来源 访问地区 设备类型
结合:
限制异常请求。
用户 │ ▼ Resume Download │ ┌─────────┴─────────┐ ▼ ▼ ResumeDownload PDF Engine │ │ ▼ ▼ Database pdf-lib │ ▼ Watermark │ ▼ Resume PDF
一个简单的简历下载功能,通过加入动态水印后,可以升级成为一个完整的文件追踪系统。
整个实现过程包括:
对于个人开发者网站来说,这是一套成本低,但是非常实用的工程化方案。
它不仅保护了个人资料,也让个人网站具备更加完整的数据分析能力。
暂无评论,留下第一条声音吧。