nodejs+phantom html转pdf问题整理

简单说下背景:为了实现本人一个云开发小程序《微作简历》的简历下载,不得不自己摸索着搞一搞简单服务端。于是就有了这一次的爬坑经历。在决定通过接口下载文件之后。选了选使用的技术(++加黑字体是我最终选用的技术++).

  1. 搭建简易后台服务器:nodejs+express
  2. 实现html转pdf的工具:html-pdf,wkhtmltopdf,phantom
  3. phantom要爬取的web网页以便生成pdf: 绘制简历模板页面放入web服务器上

一,实现需求的思路

a: 小程序客户端

b: 小程序云开发

c: nodejs+express后台服务

d: nodejs web 网页服务

==a== 长按事件触发下载接口调用 ==c== 的接口触发==d==网页请求==c==向==b==请求数据返回渲染页面后由==d==抓取页面并生成pdf文件后返回流至==a==

graph LR

a --> c

c --> d

d --> c

c --> b

二,问题及处理

1. web服务器通过ip+端口号访问可行,通过域名加端口号访问不可行?

可以看出之所以域名+端口号访问不成功是因为刚开始启动的serve.js中listen()未入参hostname,加入hostname之后就可以了。参照nodejs/server.listen

    web 服务器启动脚本serve.js
    
    let http = require("http");
    let fs = require("fs");
    let url = require("url");
    let path = require("path");

    let root = path.resolve(process.argv[2]||'.')
    let dir = process.argv[2] || ''

    console.log("path/root:"+root)
    console.log(__dirname)
    // 问题产生及解决 start
    // const hostname = '0.0.0.0';
    const port = normalizePort(process.env.PORT || '8081');

    const server = http.createServer(app);
    server.listen(port, () => {
        console.log(`Server running at prot:${port}/`);
    });
    // server.listen(port, hostname, () => {
    //    console.log(`Server running at http://${hostname}:${port}/`);
    // });
    // 问题产生及解决 end
    function normalizePort(val) { // 判断有无端口号
        var port = parseInt(val, 10);
      
        if (isNaN(port)) {
          // named pipe
          return val;
        }
      
        if (port >= 0) {
          // port number
          return port;
        }
      
        return false;
    }

    function app(request, response) {
        // 解析请求
        let pathName = __dirname + url.parse(request.url).pathname
        let pageUrl = pathName.charAt(pathName.length - 1) == "/"?(pathName+="index.html"):pathName
        // 获得对应本地文件路径
        // let filepath = path.join(root, pageUrl)
        // 获取文件状态
        fs.stat(pageUrl,(err, stats)=>{
            if(!err && stats.isFile()) {
                // 文件存在且正常
                response.writeHead(200);
                fs.createReadStream(pageUrl).pipe(response)
            } else {
                response.writeHead(404);
                // response.end('404 Page')
                fs.createReadStream(__dirname + "/index.html").pipe(response)
            }
        })
    }

    
  1. 后台服务器phantom做的html2pdf接口,本地测试可行,上传服务器后不可行,具体问题细分如下:(后台服务器搭建参照nodejs,express,mysql搭建web服务器(提供api接口))
  • linux cents os系统 npm安装phantom失败
代码上传至服务器,npm i。会报错phantomjs-2.1.1-linux-x86_64.tar.bz2解压失败
经排查.bz2解压需要安装bzip2,yum -y install bzip2.x86_64。安装成功之后再次npm就可以了  
  • 服务器上 phantom 执行报错EPIPE Write

stark overflow / PhantomJS from Node on Windows

Linux/Centos下安装部署phantomjs 及使用

此错误,查询半天在stark overflow的一篇相关问答中,回答者提出依赖环境相关概念,而后在一篇博客中有着linux/cents os下部署phantomjs。

yum install fontconfig freetype2

执行语句安装依赖之后,该问题解决

  • 本地转化生成pdf数据健全,服务器上生成pdf缺失

phantomjs乱码问题生产环境处理方案

服务器上生成pdf,打开一看里面只有数字,或者英文,数据残缺。
一开始我以为是phantomjs在页面未渲染完毕前转化导致,后经一位
后端开发朋友提醒可能是缺失中文字体导致的。遂按照这个思路在csdn上的一篇文章中按照步骤安装字体后成功解决。

  1. http添加ssl使用https供小程序调用
    本人使用的阿里云服务器,按照相关文档使用了免费的ssl.不做细说
  1. 参数路由传递过程中,解析报错

js字符串转换为对象格式

http://url?testObj={"a":123,"b":456}

解析testObj时报错
string转obj的三种方式
1,JSON.parse(str)
2, new Function('return '+str)()
3, eval("(" + str + ")");
最终解决,严格按照JSON格式传入数据{"key":"value","key2":"value2"}采用JSON.parse(str)


end

以上为本次dome所遇到的问题,以及翻阅的相关文章。

你可能感兴趣的:(nodejs+phantom html转pdf问题整理)