当前位置: 首页 > 知识库问答 >
问题:

打开具有特定配置的Puppeteer(下载PDF而不是PDF查看器)

常英纵
2023-03-14

我想打开具有特定配置的Chromium。

我正在寻找激活以下选项的配置:

背景=

我在这个命令行切换页面上搜索了标签,但是处理pdf的唯一参数是--print to-pdf,这与我的需要不一致。

你有什么想法吗?

共有2个答案

郎鸿雪
2023-03-14

Puppeter目前不支持在无头模式下轻松导航(或下载)PDF。从页面的文档中引用。转到功能:

注意无标题模式不支持导航到PDF文档。见上游问题。

不过,您可以做的是检测浏览器是否导航到PDF文件,然后通过节点自行下载。js。

代码示例

const puppeteer = require('puppeteer');
const http = require('http');
const fs = require('fs');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    page.on('request', req => {
        if (req.url() === '...') {
            const file = fs.createWriteStream('./file.pdf');
            http.get(req.url(), response => response.pipe(file));
        }
    });

    await page.goto('...');
    await browser.close();
})();

这将导航到URL并监视正在进行的请求。如果找到匹配请求,Node.js将通过http.get手动下载文件,并将其导入file.pdf。请注意,这是一个最小的工作示例。您希望在下载时捕获错误,也可能希望根据情况使用比http.get更复杂的东西。

在未来,可能会有一种更简单的方法。当Puppeter支持响应拦截时,您可以简单地强制浏览器下载文档,但目前不支持(2019年5月)。

夹谷成仁
2023-03-14

没有任何选项可以传递到Puppeter来强制下载PDF。但是,您可以使用ChromeDevTools协议添加内容处置:附件响应头以强制下载。

您需要执行的操作的可视化流程:

我将在下面包括一个完整的示例代码。在下面的示例中,PDF文件和XML文件将以头部模式下载。

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回购协议(附带注释)。它还包括剧作家的示例代码。

 类似资料:
  • A)有没有一种方法可以下载在Chrome中使用脚本显式打开的PDF?B)有没有一种方法可以从打开的网页中提取URL,然后反馈到程序中下载?

  • 问题内容: 我想知道如何使PDF文件链接可下载,而不是在浏览器中打开它们?如何在html中完成?(我认为这是通过javascript或其他方式完成的)。 问题答案: 您无法使用HTML执行此操作。这是基于服务器的解决方案。您必须流式传输文件,以便浏览器触发保存对话框。 我建议不要这样做。用户如何与PDF交互应由用户决定。 更新: 所以…这个答案仍然有很多不足之处。我认为部分原因是这是4年前回答的,

  • 我使用以下代码存储pdf文件: 之后在onActivityResultIm使用OutputStream保存数据。Uri到文件可以看起来像: 但当我试图以此目的启动活动时,pdf viewer应用程序显示错误: 是否可以从内容Uri打开pdf查看器活动?

  • 问题内容: 我正在使用Java和RCP,并且尝试在Acrobat上显示pdf文档。我不需要更改它们。我的这段代码有这个错误。任何想法如何解决这个问题?附言:它同时运作良好。 问候,Haythem 问题答案: 看看这些免费的pdf渲染器… 一些链接… http://www.icepdf.org/(现在位于http://www.icesoft.org/java/projects/ICEpdf/over

  • 问题内容: 我的公司需要具有Java API的PDF查看器,并具有使用FDF表单数据的附加要求。 我发现的唯一一个是JPedal,它承诺将提供我们需要的所有功能,但花费很多。那我有什么选择呢?还有其他工具可以做到吗? 编辑: 我发现iText是将FDF数据合并到PDF表单中的简便方法。 Sun的pdf-renderer是唯一可以 正常 工作的LGPL查看器(不同于Adobe自己使用的10年的Jav