gpt4 book ai didi

node.js - 在使用 Nightmare JS 的 AWS 上,导出为 PDF 可以使用一个端口,但不能使用另一个端口

转载 作者:行者123 更新时间:2023-12-03 13:23:57 25 4
gpt4 key购买 nike

我在将财务数据通过电子邮件发送给用户的应用程序中具有导出到 PDF 的功能。我使用我的测试站点获得了这个功能 100% 工作,但是当我部署到我的生产站点时它没有工作。在 prod 站点上,通过电子邮件向用户发送一个空白的 1kb 1 页 PDF 文件(可以在 PDF 查看器中打开)。

这是我如何使用该功能的低点。我用过这个guide让 Nightmare JS 在 Amazon Linux 上运行。

  • 服务器导出收到 /export调用
  • 调用使用 xvfb-run 的子进程为 Nightmare JS 创建一个可视帧缓冲区以供使用。
    exec(`xvfb-run -a --server-args="-screen 0 1366x768x24" node 
    ${path.join(__dirname, 'export.js')} ${process.env.TYPE} ${token}
    ${req.user.email}`)
  • 在 export.js 进程中,Nightmare JS 从站点运行的端口(测试站点:端口 3001,生产站点:3000)执行 HTTP 浏览器加载。
    Nightmare()
    .viewport(1366, 768)
    .goto(
    `http://localhost:${process.env.PORT}/export_summary_1?
    exportToken=${exportToken}`
    )
    .wait(3000)
    .pdf()
    .end()
    .then(function(pdfBuffer) {
    mailOptions.attachments = [{
    filename: 'financial_model.pdf',
    content: pdfBuffer
    }]
    email.send(mailOptions)
    })
  • /export_summary_1浏览器页面使用导出 token 进行另一个服务器调用以加载和显示财务数据。然后,如上面的代码所示,Nightmare 将页面捕获为 PDF,最后将该 PDF 通过电子邮件发送给用户。


  • 我不相信我的 AWS 设置是罪魁祸首,因为导出到 PDF 系统的相关部分都是在 AWS 实例上本地完成的(例如,Nightmare 页面加载完成到 http://localhost:[port]/export_summary_1 )。

    我确实有一个 HTTP->HTTPS 重定向,但是我绕过了 Nightmare 页面加载和加载页面的服务器调用来检索财务数据。

    尽管我不认为问题出在我的 AWS 设置上,但这是我在 上的笔记AWS 和端口设置 , 为了完整性。
  • 我的实例使用的安全组中启用了端口 3000 和 3001。
  • 负载均衡器设置
  • 端口 80 和 443 监听器转发到“ec2-instance-targets”,它使用端口 3000 将 AWS 实例作为注册目标。
  • 端口 3001 监听器转发到“ec2-devInstance-targets”,它使用端口 3001 将 AWS 实例作为注册目标。

  • 此外,AWS 实例是“ec2-instance-targets” View 中的“不健康”注册目标(“ec2-instance-targets”用于产品站点)。这是因为,我相信“ec2-instance-targets”目标组的端口设置为 80,而注册目标的端口设置为 3000。

    但是,prod 站点仍然有效,正如我之前所说,这些 AWS/负载均衡器设置似乎不是问题来源,因为导出到 PDF 系统包含在 AWS 实例中,出于所有意图和目的。

    虽然,我确实计划在几个小时内解决上述问题,那时对我来说是晚上。

    此外,我还注释掉了 Nightmare 加载页面对服务器的财务数据调用。现在,导出为 PDF 的加载页面上只有“hello world”文本。问题仍然存在。

    如何在 prod 网站上使用导出到 PDF 功能?

    最佳答案

    tldr; NightmareJS 加载了一个空白页面,该页面导出为 PDF,因为有对 https://localhost:3000/bundle.js 的子调用和 https://localhost:3000/styles/style.css ,它们负责所有呈现的无法连接的内容(没有设置 HTTPS 服务器,因为 HTTPS 是通过 AWS 负载均衡器实现的)。

    在我的问题中,我提到了我认为导出到 PDF 处理的相关部分都是在本地完成的。实际上就是这种情况,但还有进一步的 HTTP->HTTPS 重定向。以下是 HTTP->HTTPS 重定向代码的外观:

    app.use(function(req, res, next) {
    if(!req.secure &&
    req.get('X-Forwarded-Proto') !== 'https' &&
    // above: achieves HTTP->HTTPS redirecting using AWS load balancer and EC2 instance
    !/export_summary/.test(req.url)) {
    res.redirect('https:' + req.hostname + req.url)
    } else {
    next()
    }
    })
    // NOTE: all code above is commented out on test site, and uncommented for production site

    这是 Stackoverflow page解释如何使用 AWS 负载均衡器和 EC2 实例实现 HTTP->HTTPS 重定向,以及上面代码中使用的内容。

    当我最初将导出到 PDF 功能部署到 prod 站点时,我收到一个 NightmareJS 错误,通知我 https://localhost:3000/export_summary无法到达。所以,我插入了 !/export_summary/.test(req.url)有条件的,以便 NightmareJS 对 export_summary 的 HTTP 调用页面不会被重定向到 HTTPS 调用。

    上面的代码块也作用于 NightmareJS 加载 export_summary 所涉及的子调用。页。所以,资源的两个主要子调用,到 http://localhost:3000/bundle.jshttp://localhost:3000/styles/style.css , 被重定向到他们的 HTTPS 对应项。 (注意:在为 <script src='bundle.js'></script> 提供的 HTML 文件中,bundle.js 调用是 /export_summary

    由于 AWS 实例上没有设置实际的 HTTPS 服务器,因此这些子调用无法连接(客户端会将此报告为“连接被拒绝”错误消息)。应用程序的 HTTPS 是通过 AWS 负载均衡器实现的。

    这两个资源负责应用程序的全部呈现内容。因此,没有它们,加载的页面是白色和空白的,如导出的 PDF 所示。

    此外,正如上面代码块中的注释所述,HTTP->HTTPS 重定向代码在测试站点上被注释掉了。这解释了我是如何看到该功能在测试站点上按预期工作的,因为麻烦的中间件不是处理的一部分。

    解决方案

    我更新了绕过 HTTP->HTTPS 重定向的条件,还包括相关的子调用:
    !/(export_summary)|(exportPrivate)|(bundle\.js)|(style\.css)|(\.png)|(\.ttf)|(\.woff)/.test(req.url))

    注意:PNG、TTF 和 WOFF 资源调用也需要被绕过,因为它们是完整、精美的 PDF 所必需的。

    最后,我认为这里没有安全风险,尽管我认为当然可以进行安全改进。
  • bundle.js、style.css 和图像/字体文件中不保存任何 secret 数据。
  • 对于 /export_summary调用时,服务器会响应一个 index.html 文件,该文件用于部署应用程序(那里也没有 secret 数据)。
  • 绕过对包含“exportPrivate”子字符串的端点的调用是为了让 NightmareJS 调用加载导出为 PDF 的用户数据。由于允许跨 HTTP 调用,因此不会在 Internet 上使用此调用。它只允许在服务器上使用 headless 客户端浏览器,例如 NightmareJS。

  • 欢迎任何有关改进解决方案安全方面的建议。

    关于node.js - 在使用 Nightmare JS 的 AWS 上,导出为 PDF 可以使用一个端口,但不能使用另一个端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48675145/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com