团检报告生成方案遇到的一些问题
之前做了一套团检报告生成方案 - 上篇博文。期间有遇到一些问题,今天有空归纳总结了一下,整套方案的运行效果还是很理想的,当然我们的业务访问量其实不大,不然有可能会暴露出更多的问题,特别是 puppeteer 是很耗内存资源的,在访问量大的情况下,可能要去重点优化 puppeteer 的使用效率问题,但以现在公司的业务基本不用太担心这个问题。
问题 1: 团检报告的数据中中文字符会乱码
我在 node 起了一个 next app 服务,其中包含 /pages/* 下的页面资源和 /api/* 下的 接口资源。
接口资源如下:
- POST /api/html2pdf
- GET /api/healthcheck
/api/html2pdf
用来生成将指定的 html 页面转成 PDF 文档,接收以下参数:
1 | { |
页面资源如下:
- teamreport
访问 http://localhost/teamport 会返回 Next SSR 的 html 文档,这是一份带有图表,表格,插图等的体检报告。其中报告里的数据通过在 puppeteer 的 setExtraHeader 取得page.setExtraHeader,整体流程如下:
1 | 1. POST /api/html2pdf |
由于团检报告 json 数据中是会包含一些中文字符的,比如一些医学名称,例如高血压、高血脂等等。在 api/html2pdf
拿到的 extraHeader 还是正常的 JSON.stringify 后的文本,中文也是正常显示。但是当整份数据需要通过 page.setExtraHeaders
的形式给到 puppeteer 打开的 page 时,在 page 拿到的数据中的中文会乱码,想必是 puppeteer 在 page.setExtraHeaders
的时候对特殊字符做了一些转译。
解决方法:对 JSON.stringify 后的文本(extraHeaders)进行 再 encodeURI 处理,然后才 setExtraHeaders
1 | encodeURI(JSON.stringify(reportData)); |
这样就“消灭”了中文字符,在新打开的 page 里再通过 decodeURI 对 encode 的特殊字符进行解码,中文特殊字符就能正常通过 page header 的形式给到 page 了。但也因此产生了问题 2
问题 2:puppeteer.page.setExtraHeaders()设置的 header 文本过长
当体检报告的数据(>10kb)过大的时候,有可能超过 HTTP header 的最大限制,而 HTTP header 支持的最大长度会根据 web 服务器不同而有不同的限制。项目中使用 encodeURI 去对中文字符进行转译也会额外增加 header 的长度。
所以,使用 header 并不适合用来传输大量数据。
解决方案 1:
使用 node 全局变量,页面渲染完后即销毁。