小智 7
没有选项可以传递给 Puppeteer 来强制下载 PDF。但是,您可以使用 chrome-devtools-protocol 添加content-disposition: attachment响应标头以强制下载。
您需要做的事情的可视化流程:

我将在下面包含一个完整的示例代码。在下面的示例中,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();
})();
Run Code Online (Sandbox Code Playgroud)
有关更详细的解释,请参阅我已设置的带有注释的Git 存储库。它还包括playwright的示例代码。
Puppeteer 目前不支持在无头模式下轻松导航(或下载)PDF。引用该page.goto函数的文档:
注意无头模式不支持导航至 PDF 文档。请参阅上游问题。
不过,您可以做的是检测浏览器是否正在导航到 PDF 文件,然后通过 Node.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();
})();
Run Code Online (Sandbox Code Playgroud)
这会导航到 URL 并监视正在进行的请求。如果找到“匹配的请求”,Node.js 将通过管道手动下载文件http.get并将其传输到file.pdf. 请注意,这是一个最小的工作示例。您希望在下载时捕获错误http.get,并且可能还希望根据情况使用更复杂的东西。
将来,可能会有更简单的方法来做到这一点。当 puppeteer 支持响应拦截时,您将能够简单地强制浏览器下载文档,但目前不支持此功能(2019 年 5 月)。
| 归档时间: |
|
| 查看次数: |
3131 次 |
| 最近记录: |