使用DOMPDF(WP PDF Templates)访问localStorage时渲染异常问题
为什么会出现这个问题?
DOMPDF是服务器端的PDF生成工具,它运行在服务器环境中,完全没有浏览器的window、localStorage这类客户端专属的API。你原页面的JS代码依赖浏览器的localStorage存储数据,但DOMPDF解析HTML时,根本找不到localStorage对象,所以会抛出ReferenceError: localStorage is not defined的错误。
另外,PDF页面的localStorage为空是正常的:原页面的localStorage是存储在你本地浏览器的当前域名下,而PDF生成页面是服务器端生成后返回的全新页面,和原页面属于不同的渲染上下文,服务器不会主动把客户端的localStorage数据带到PDF生成流程里。
可行的解决方法
1. 服务器端传递数据
把原页面localStorage里的score数据,通过HTTP请求传递给服务器(比如GET参数、POST表单),服务器在生成给DOMPDF的HTML时,直接把数据嵌入到页面中,不需要客户端JS再读取localStorage。
举个简单的例子(假设用Node.js模板引擎):
- 客户端把
score数据通过请求传给服务器:// 原页面的JS,在触发生成PDF时 const score = JSON.parse(localStorage.getItem('score')); // 跳转到PDF生成页面,把score作为GET参数传递 window.location.href = `/reference-page/pdf?score=${encodeURIComponent(JSON.stringify(score))}`; - 服务器接收参数后,在HTML模板中直接渲染内容:
或者嵌入全局变量让JS使用(但此时不需要读localStorage):<!-- 服务器模板渲染的HTML --> <div id="answer-1"> <% if (score.includes(1)) { %> <button id="q1" type="button" class="btn answer-btn m-0">STRONGLY DISAGREE</button> <% } %> </div><script> const UserScoreResults = <%- JSON.stringify(score) %>; // 后续渲染逻辑不变,但跳过localStorage读取步骤 </script>
2. 预渲染HTML后再转PDF
如果必须依赖客户端渲染逻辑,可以先在浏览器里把页面完全渲染好(JS执行完毕,数据已经展示到DOM中),然后把整个渲染后的HTML代码传给服务器,再用DOMPDF处理这个现成的HTML。
示例代码:
// 原页面中,页面渲染完成后获取完整HTML const renderedHtml = document.documentElement.outerHTML; // 通过AJAX把HTML发给服务器的PDF生成接口 fetch('/generate-pdf', { method: 'POST', headers: { 'Content-Type': 'text/html' }, body: renderedHtml }).then(res => res.blob()).then(blob => { // 下载生成的PDF const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'results.pdf'; a.click(); });
服务器端接收HTML后,直接传入DOMPDF生成PDF即可。
3. 改用服务器端存储
把原本存在localStorage的数据,迁移到服务器端存储(比如Session、数据库),用户完成答题后直接把数据提交到服务器保存。生成PDF时,服务器直接从存储中读取数据,渲染对应的HTML内容,完全不依赖客户端的存储。
内容的提问来源于stack exchange,提问作者Ruan Petersen

