如何解决Express框架下Pug模板无法加载CSS与静态图片的问题
问题根因
你没有通过Express的res.render方法渲染pug模板,而是直接调用pug.compileFile将模板编译为HTML字符串后传给Puppeteer,此时生成的HTML里的相对路径没有对应静态资源根目录的映射,Puppeteer无法通过相对路径定位到public目录下的资源。
解决方案
方案1:补全静态资源的绝对访问路径
这是适配性最高、改造成本最低的方案:
- 编译pug模板时传入服务的基础地址参数:
// 路由checklist.js中修改编译逻辑 const path = require('path') const compiledFunction = pug.compileFile(path.join(__dirname, '../views/checklist.pug')); const htmlContent = compiledFunction({ ...checklist, // 本地测试用本地地址,部署后替换为线上域名 baseUrl: 'http://localhost:3000' });
- 修改pug模板中的资源路径,拼接传入的基础地址:
link(href=`${baseUrl}/stylesheets/checklist.css` rel='stylesheet') img(src=`${baseUrl}/images/logo.png` alt='Logo...')
方案2:将静态资源内联到HTML中
该方案不依赖Express服务运行,离线也可正常生成PDF:
- 提前读取资源内容传入模板:
// checklist.js中提前读取资源内容 const fs = require('fs'); const path = require('path') // 读取CSS内容 const cssContent = fs.readFileSync(path.join(__dirname, '../public/stylesheets/checklist.css'), 'utf-8'); // 图片转base64 const logoBase64 = `data:image/png;base64,${fs.readFileSync(path.join(__dirname, '../public/images/logo.png'), 'base64')}` const htmlContent = compiledFunction({ ...checklist, cssContent, logoBase64 });
- 修改pug模板,用内联资源代替外部引用:
head style !{cssContent} body div(class='checklist-title') img(src=logoBase64 alt='Logo...')
方案3:设置Puppeteer页面的基础路径
不需要修改模板路径,仅修改Puppeteer逻辑:
const page = await browser.newPage(); // 先访问服务根地址,确认基础路径 await page.goto('http://localhost:3000'); await page.setContent(htmlContent, { waitUntil: 'networkidle2' });
内容的提问来源于stack exchange,提问作者dividebyzero
相关产品推荐
相关产品推荐

