【问题标题】:Download files using puppeteer does not store file in /tmp folder of google cloud functions使用 puppeteer 下载文件不会将文件存储在谷歌云功能的 /tmp 文件夹中
【发布时间】:2021-09-12 14:26:21
【问题描述】:

我想模拟使用 puppeteer 的下载功能,并且 puppeteer 脚本在云函数中运行。我触发了下载按钮并将下载路径设置为 /tmp/ 但是当我从 /tmp 读取文件时,我下载的文件没有显示在那里。有时它会随机显示在那里。

    const page = await browser.newPage();
    await page.setDefaultNavigationTimeout(0);
    await page.goto(url);

    const downloadPath = `${os.tmpdir()}` + '/'; 
    await page._client.send('Page.setDownloadBehavior', {
        behavior: 'allow',
        downloadPath
    });

    await page.reload({ waitUntil: 'networkidle0' });

    const filename = `test-report.pdf`;
 
    await page.click('#screenshot'); //simulate download 
    await page.waitForTimeout(4000);

    const files = fs.readdirSync(downloadPath);
    console.log('Dir files ', files);
    const filePath = downloadPath + filename;
    const content = fs.readFileSync(filePath).toString("base64");

    await page.close();

这个错误来了:

在 /tmp/report.pdf 中找不到文件。

如何解决?

puppeteer 版本为 ^10.0.0,Node js 版本为 12

【问题讨论】:

    标签: node.js google-cloud-functions pdf-generation puppeteer screenshot


    【解决方案1】:

    这是我尝试过的,它似乎有效:

    server.js

    const os = require('os');
    const fs = require('fs');
    const puppeteer = require('puppeteer');
    
    exports.screenshot = async(req, res) => {
    
      // Asking for a URL to download 
      const url = req.query.url;
      if (!url) {
        return res.send('Please provide URL as GET parameter, for example: <a href="?url=https://example.com">?url=https://example.com</a>');
      }
    
      const downloadPath = `${os.tmpdir()}` + '/';
      const filename = 'example.pdf';
      const mypath = downloadPath + filename;
    
      const browser = await puppeteer.launch()
      const page = await browser.newPage()
    
      // Create PDF from URL
      await page.goto(url)
      await page.pdf({
        path: mypath,
        format: 'A4'
      })
    
      await page.close();
      await browser.close()
    
      // Check if file is in Cloud Function /tmp/
      if (fs.existsSync(mypath)) {
        console.log("exists:", mypath);
        res.sendStatus(200);
      } else {
        console.log("DOES NOT exist:", mypath);
        res.sendStatus(500);
      }
    }

    package.json

    {
    "name": "screenshot",
    "version": "1.0.0",
    "description": "Takes screenshot of the given URL, then checks if the download was successful",
    "author": "",
    "scripts": {
        "start": "node server.js"
    },
    "dependencies": {
        "express": "^4.16.4",
        "os": "^0.1.1",
        "fs": "0.0.1-security",
        "puppeteer": "^1.10.0"
    }
    

    但请注意 Cloud 函数 /tmp/ 文件夹是 RAM,因此请确保您存储的所有临时文件都将被删除,如 here 解释的那样

    确保分配足够的内存,我在测试时遇到了一些内存限制问题,我意识到在下载中等大小的页面时它使用了大约 400mib。
    如果您打算下载大页面,我建议至少分配 512mib 或 1Gib。

    【讨论】:

    • 谢谢@Lluis Muñoz。当我尝试生成 pdf 时它正在工作,但在这里我正在模拟下载行为,它将文件下载到 /tmp 文件夹中。但它无论如何都不会进入/tmp。没错,我已经分配了 1 GB 内存
    【解决方案2】:

    我会使用,它过去对我有用

    const file = fs.createWriteStream("/tmp/yourfile.yxz");

    而不是

    const downloadPath = ${os.tmpdir()} + '/';

    【讨论】:

    • 谢谢@Chris32,你能解释一下并稍微调整一下代码吗?太好了,我不明白。再次感谢。
    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2015-08-03
    • 2014-07-20
    • 2015-04-29
    • 1970-01-01
    • 2023-02-13
    相关资源
    最近更新 更多