Handlebars模板中图片无法渲染的问题排查求助
问题解决:Handlebars模板编译后图片无法渲染(Puppeteer生成PDF场景)
你遇到的核心问题是:直接用page.setContent传入编译后的HTML时,Puppeteer是在无服务器上下文的环境加载本地HTML,Express的静态资源配置对它无效——因为Express的静态服务是给HTTP请求用的,而这里的HTML字符串里的相对路径sign.png,Puppeteer会尝试从当前工作目录找,而不是你设置的assets文件夹。
下面是几种可行的解决办法:
方法一:使用图片的绝对文件路径
修改Handlebars模板里的图片引用,通过Node.js的path模块生成绝对路径,让Puppeteer能直接定位到图片:
- 编译模板时,把图片的绝对文件路径传入数据:
const imagePath = path.join(process.cwd(), 'assets', 'sign.png'); const jsonData = { // 你的其他自定义数据 signImagePath: `file://${imagePath}` };
- 在Handlebars模板中引用这个路径:
<img src="{{signImagePath}}"/>
方法二:让Puppeteer访问Express服务器的页面
既然已经配置了Express静态资源,可以先启动Express服务器,让Puppeteer请求对应的路由页面,而非直接传入HTML字符串:
- 给Express添加返回编译后页面的路由:
app.get('/passes', async (req, res) => { const content = await compile('Passes', jsonData); res.send(content); }); // 启动服务器监听端口,比如3000 const server = app.listen(3000, () => { console.log('Server running on http://localhost:3000'); });
- 修改Puppeteer代码,访问该路由页面:
const browser = await puppeteer.launch(); const page = await browser.newPage(); // 等待页面及资源加载完成 await page.goto('http://localhost:3000/passes', { waitUntil: 'networkidle2' }); await page.emulateMediaType('screen'); await page.pdf({ path: 'PASSES/' + filenameWE + '.pdf', format: 'A4', printBackground: true }); console.log("Done ---- " + filenameWE); await browser.close(); server.close(); // 生成PDF后关闭服务器
这种方式能直接利用Express的静态资源配置,图片的相对路径会被正确解析到assets文件夹。
方法三:将图片转为Base64嵌入HTML
把图片转成Base64编码后直接嵌入模板,无需依赖外部文件:
- 编写工具函数读取图片并转换为Base64:
const getImageBase64 = async (imagePath) => { const imageBuffer = await fs.readFile(imagePath); return `data:image/png;base64,${imageBuffer.toString('base64')}`; };
- 编译模板前传入Base64格式的图片数据:
const signBase64 = await getImageBase64(path.join(process.cwd(), 'assets', 'sign.png')); const jsonData = { // 你的其他自定义数据 signBase64: signBase64 };
- 在Handlebars模板中引用:
<img src="{{signBase64}}"/>
内容的提问来源于stack exchange,提问作者Usman Amjad
相关产品推荐
相关产品推荐

