You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地正常的HTML转PDF API部署Azure Web Services后超时故障排查

问题分析与解决方案

1. 修复 TypeError: Cannot read properties of undefined (reading 'status') 错误

该错误根源是回调函数参数名与外层Express响应对象res重名:在pdf.create的回调中,你用了res作为参数,覆盖了外层的Express响应对象。当生成PDF出错时,回调内的res并非Express响应对象,而是html-pdf返回的错误结果(此时为undefined),调用res.status()自然会报错。

修复后的代码:

function generatePDF(req, res) {
    const htmlContent = req.body.html;
    return new Promise((resolve, reject) => {
        // 将回调参数res改为result,避免覆盖外层响应对象
        pdf.create(htmlContent, options).toFile("./public/docs/doc.pdf", (err, result) => {
                if (err) {
                    console.log(err);
                    res.status(500).send("Une erreur s'est produite lors de la creation du fichier Pdf");
                    reject(err); // 出错时用reject传递错误,而非resolve
                } else {
                    console.log("Le fichier Pdf a été généré dans le serveur");
                    resolve(result);
                }
            });
    });
}

额外优化:

  • 原代码中包裹Promise的try/catch无效,因为pdf.create是异步操作,错误不会被外层同步try/catch捕获,直接删除即可。
  • 出错时调用reject(err),让外层await能捕获错误,避免后续执行readPDF读取不存在的文件。

2. 解决Azure环境中html-pdf: PDF generation timeout. Phantom.js script did not exit错误

本地正常但Azure超时,核心是PhantomJS在Azure App Service环境的兼容性或配置问题,可按以下顺序尝试方案:

方案1:延长PhantomJS超时时间

默认超时时间可能不足以在Azure环境完成PDF生成,在配置中增加超时设置:

const options = {
    "height": "14cm",
    "width": "20cm",
    "border": "0",
    "header": { "height": "0mm" },
    "footer": { "height": "0mm" },
    "timeout": 30000 // 延长至30秒,可根据实际情况调整
}

方案2:检查文件路径与写入权限

Azure App Service的文件系统有读写限制,建议使用临时目录或确保目标目录存在:

const fs = require('fs');
const path = require('path');

// 优先使用Azure临时目录,避免权限问题
const savePath = process.env.TEMP || path.join(__dirname, '../public/docs');
// 确保目录存在,不存在则创建
fs.mkdirSync(savePath, { recursive: true });

// 修改保存路径
pdf.create(htmlContent, options).toFile(path.join(savePath, 'doc.pdf'), ...);

方案3:切换Azure App Service至Linux环境

PhantomJS在Windows环境下兼容性较差,切换到Linux环境大概率能解决超时问题:

  1. 登录Azure门户,找到你的Web App
  2. 进入「配置」>「常规设置」
  3. 将「操作系统」改为Linux,保存后重新部署代码

方案4:替换为维护中的PDF生成库

node-html-pdf已停止维护(最后更新于2018年),依赖的PhantomJS也已废弃。推荐替换为Puppeteer(基于Chromium),在Azure环境稳定性更强:

const puppeteer = require('puppeteer');

async function generatePDF(req, res) {
    const htmlContent = req.body.html;
    const browser = await puppeteer.launch({
        args: ['--no-sandbox', '--disable-setuid-sandbox'] // Azure环境必需参数
    });
    const page = await browser.newPage();
    await page.setContent(htmlContent);
    const pdfBuffer = await page.pdf({
        height: "14cm",
        width: "20cm",
        margin: { top: 0, bottom: 0, left: 0, right: 0 }
    });
    await browser.close();
    return pdfBuffer;
}

exports.generatePDFfromHTML = async function (req, res) {
    try {
        const pdfBuffer = await generatePDF(req, res);
        res.status(200).send(pdfBuffer.toString('base64'));
    } catch (err) {
        console.log(err);
        res.status(500).send("Erreur lors de la génération du PDF");
    }
}

3. 额外优化:避免无效的文件读取

原代码中generatePDF失败后仍会执行readPDF,导致读取不存在的文件。修改外层函数,用try/catch控制流程:

exports.generatePDFfromHTML = async function (req, res) {
    try {
        await generatePDF(req, res);
        readPDF(req, res); 
    } catch (err) {
        console.log(err);
        res.status(500).send("Erreur lors de la génération du PDF");
    }
}

内容的提问来源于stack exchange,提问作者Yannick Makwenge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:30:01