You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Express POST路由跳转后PDF预览404问题排查与解决

解决Node.js/Express中PDF生成后即时跳转404的问题

嘿,这个问题我之前也踩过一模一样的坑!你怀疑的时序问题完全正确——wkhtmltopdf是异步执行的,但你的服务器代码在PDF还没生成完成的时候就直接返回了文件URL,导致客户端跳转过去时文件还没写完(甚至还没创建),自然触发404错误。刷新后文件已经生成完毕,所以能正常访问。下面是具体的修复方案:

核心问题:异步操作未等待完成

你的服务端代码直接调用wkhtmltopdf(formText, options)后,立刻执行压缩、邮件发送并返回响应,但wkhtmltopdf是异步的,这些后续操作和响应返回都发生在PDF生成完成之前。我们需要等待PDF生成完成后再执行后续逻辑并返回URL。

修复服务端代码(等待PDF生成完成)

利用wkhtmltopdf的回调函数(或Promise)确保文件生成后再继续:

app.post('/', function (req, res) {
  const formText = req.body.formText;
  const fileName = req.body.fileName;
  console.log(fileName);

  const wkhtmltopdf = require('wkhtmltopdf');
  const options = {
    'page-size': 'Letter',
    'margin-top': '0.75in',
    'margin-right': '0.75in',
    'margin-bottom': '0.75in',
    'margin-left': '0.75in',
    'encoding': "UTF-8",
    'dpi': 800,
    'output': `./public/pdfs/${fileName}`,
  };

  // 等待PDF生成完成的回调
  wkhtmltopdf(formText, options, function(err) {
    if (err) {
      console.error('PDF生成失败:', err);
      return res.status(500).json({error: 'PDF生成失败,请重试'});
    }
    console.log('pdf generated');

    // 现在PDF已存在,再执行压缩
    const zipName = zipFile(fileName);
    console.log('zip generated:' + zipName);

    // 执行邮件发送(如果emailFile是异步的,也需要等待其完成,比如用回调或Promise)
    emailFile();

    // 此时文件肯定已生成,安全返回URL
    const responseData = { fileURL: `http://localhost:3000/pdfs/${fileName}` };
    res.json(responseData); // 用res.json更简洁,自动处理Content-Type和长度
  });
});

修复客户端代码(移除不稳定的延迟)

现在服务器返回URL时文件已经存在,不需要再用setTimeout,直接跳转即可:

$("#testPostButton").click(function () { 
  const fileName = fileNamer(); 
  const formText = $("#formText").html(); 
  $.ajax({ 
    url: '/', 
    type: 'POST', 
    contentType: 'application/json', 
    data: JSON.stringify({formText: formText, fileName: fileName}), 
    success: function(data) { 
      console.log(data.fileURL);
      window.location = data.fileURL; // 直接跳转,无需延迟
    },
    error: function(xhr) {
      console.error('请求失败:', xhr.responseText);
      alert('PDF生成失败,请稍后重试'); // 增加错误提示提升用户体验
    } 
  }); 
});

额外提示:Content Security Policy(CSP)警告

控制台里的CSP错误是因为你的页面包含内联样式,但CSP策略的style-src未允许内联样式。解决方法:

  • 优先将内联样式移到外部CSS文件中(推荐)
  • 如果必须保留内联样式,调整CSP的style-src指令,添加'unsafe-inline'(注意:这会降低安全性),或者使用nonce/hash方式授权特定内联样式

这样修改后,就能解决即时跳转404的问题,同时让整个流程更可靠。

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

火山引擎 最新活动