node.js - 使用特定配置打开 Puppeteer(下载 PDF 而不是 PDF 查看器)

标签 node.js puppeteer

我想使用特定配置打开 Chromium。

我正在寻找配置to activate the following option :

设置 => 网站设置 => 权限 => PDF 文档 =>“下载 PDF 文件,而不是在 Chrome 中自动打开它们”

我搜索了 this command line switch page 上的标签但处理 pdf 的唯一参数是 --print-to-pdf ,它不符合我的需要。

你有什么想法吗?

最佳答案

没有任何选项可以传递到 Puppeteer 来强制下载 PDF。但是,您可以使用 chrome-devtools-protocol 添加 content-disposition:attachment 响应 header 来强制下载。

您需要做什么的直观流程:

cdp-modify-response-header (2)

我将在下面提供完整的示例代码。在下面的示例中,PDF 文件和 XML 文件将以 headful 模式下载。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    defaultViewport: null, 
  });

  const page = await browser.newPage();

  const client = await page.target().createCDPSession();

  await client.send('Fetch.enable', {
    patterns: [
      {
        urlPattern: '*',
        requestStage: 'Response',
      },
    ],
  });

  await client.on('Fetch.requestPaused', async (reqEvent) => {
    const { requestId } = reqEvent;

    let responseHeaders = reqEvent.responseHeaders || [];
    let contentType = '';

    for (let elements of responseHeaders) {
      if (elements.name.toLowerCase() === 'content-type') {
        contentType = elements.value;
      }
    }

    if (contentType.endsWith('pdf') || contentType.endsWith('xml')) {

      responseHeaders.push({
        name: 'content-disposition',
        value: 'attachment',
      });

      const responseObj = await client.send('Fetch.getResponseBody', {
        requestId,
      });

      await client.send('Fetch.fulfillRequest', {
        requestId,
        responseCode: 200,
        responseHeaders,
        body: responseObj.body,
      });
    } else {
      await client.send('Fetch.continueRequest', { requestId });
    }
  });

  await page.goto('https://pdf-xml-download-test.vercel.app/');

  await page.waitFor(100000);

  await client.send('Fetch.disable');

  await browser.close();
})();

更详细的解释请引用Git repo我已经用评论设置了。它还包括 playwright 的示例代码.

关于node.js - 使用特定配置打开 Puppeteer(下载 PDF 而不是 PDF 查看器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56254177/

相关文章:

javascript - 我使用 .catch 来捕获 promise 的拒绝,但它说我使用 .catch

node.js - 使用 Node.js 上传到谷歌云存储

javascript - Puppeteer 选择表格单元格的第 n 个子级中的链接

node.js - 如何在 Puppeteer Node js 中使用 setInterval

docker - Laravel Sail 安装 puppeteer Chrome

javascript - 如何处理 puppeteer-cluster[CONCURRENCY_BROWSER] 中的多个选项卡?

windows - npm 安装 socket.io 失败

node.js - nodejs 串口写入问题?

node.js - 处理 env 文件的最佳方法是什么?

cookies - puppeteer 中缺少请求 header