ایجاد یک API Next.js برای تبدیل HTML به PDF با Puppeteer (سازگار با Vercel)

Summarize this content to 400 words in Persian Lang
تبدیل HTML به PDF یک نیاز رایج در برنامه های کاربردی وب است. در این پست وبلاگ، نحوه ایجاد یک مسیر API Next.js را بررسی خواهیم کرد که HTML را با استفاده از Puppeteer به PDF تبدیل میکند، و مطمئن میشویم که هنگام استقرار در Vercel کار میکند.
چالش
در حالی که Puppeteer یک ابزار قدرتمند برای تبدیل HTML به PDF است، هنگام استقرار در محیطهای بدون سرور مانند Vercel با چالشهایی مواجه میشود. مسائل اصلی عبارتند از:
Puppeteer به یک باینری Chromium نیاز دارد که از محدودیت های اندازه Vercel بیشتر است.
توابع بدون سرور زمان و منابع محدودی برای اجرا دارند.
راه حل
ما از ترکیبی از @sparticuz/chromium-min و puppeteer-core برای غلبه بر این محدودیت ها در اینجا نحوه برخورد ما با آن آمده است:
از یک ساخت حداقل کرومیوم که برای محیط های بدون سرور طراحی شده است استفاده کنید.
Puppeteer را برای استفاده از این حداقل نسخه Chromium پیکربندی کنید.
فرآیند تولید PDF را برای اجرای بدون سرور بهینه کنید.
مرحله 1: راه اندازی پروژه
ابتدا یک پروژه Next.js جدید ایجاد کنید یا از یک پروژه موجود استفاده کنید. سپس، وابستگی های لازم را نصب کنید:
npm install @sparticuz/chromium-min puppeteer-core
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
برای اطمینان از سازگاری و عملکرد بهینه، مهم است که از نسخه های صحیح بسته های مورد نیاز استفاده کنید. در آخرین آزمایش، نسخه های زیر توصیه می شود:
{
“dependencies”: {
“@sparticuz/chromium-min”: “^129.0.0”,
“puppeteer-core”: “^23.5.0”
}
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مرحله 2: ایجاد مسیر API
ایجاد یک فایل جدید در app/api/html-to-pdf/route.js (برای روتر برنامه Next.js 13+) یا pages/api/html-to-pdf.js (برای روتر Pages). این هم کد:
const chromium = require(“@sparticuz/chromium-min”);
const puppeteer = require(“puppeteer-core”);
async function getBrowser() {
return puppeteer.launch({
args: […chromium.args, “–hide-scrollbars”, “–disable-web-security”],
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath(
`https://github.com/Sparticuz/chromium/releases/download/v129.0.0/chromium-v129.0.0-pack.tar`
),
headless: chromium.headless,
ignoreHTTPSErrors: true
});
}
export async function POST(request) {
try {
const { html } = await request.json();
const browser = await getBrowser();
const page = await browser.newPage();
await page.setContent(html, { waitUntil: “networkidle0” });
const pdfBuffer = await page.pdf({
format: “A4”,
printBackground: true,
margin: { top: “1cm”, right: “1cm”, bottom: “1cm”, left: “1cm” }
});
await browser.close();
return new Response(pdfBuffer, {
headers: {
“Content-Type”: “application/pdf”,
“Content-Disposition”: ‘attachment; filename=”output.pdf”‘
}
});
} catch (error) {
console.error(“Error generating PDF:”, error);
return new Response(JSON.stringify({ error: “Failed to generate PDF” }), {
status: 500,
headers: { “Content-Type”: “application/json” }
});
}
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مرحله 3: درک کد
بیایید بخش های کلیدی این کد را تجزیه کنیم:
پیکربندی مرورگر
را getBrowser تابع Puppeteer را با حداقل باینری Chromium راه اندازی می کند:
async function getBrowser() {
return puppeteer.launch({
args: […chromium.args, “–hide-scrollbars”, “–disable-web-security”],
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath(
`https://github.com/Sparticuz/chromium/releases/download/v129.0.0/chromium-v129.0.0-pack.tar`
),
headless: chromium.headless,
ignoreHTTPSErrors: true
});
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
این پیکربندی از @sparticuz/chromium-min بسته ای برای ارائه حداقل کروم باینری سازگار با محیط های بدون سرور.
نسل PDF
منطق اصلی برای تولید PDF در POST تابع:
HTML را از بدنه درخواست استخراج کنید.
یک نمونه مرورگر را با استفاده از getBrowser تابع
یک صفحه جدید ایجاد کنید و محتوای آن را به HTML ارائه شده تنظیم کنید.
یک پی دی اف از محتوای صفحه تولید کنید.
برای آزاد کردن منابع، مرورگر را ببندید.
PDF را به عنوان پاسخ با هدرهای مناسب برگردانید.
مرحله 4: استفاده از API
برای استفاده از این API، یک درخواست POST با محتوای HTML در بدنه درخواست ارسال کنید:
const response = await fetch(‘/api/html-to-pdf’, {
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify({ html: ” }),
});
if (response.ok) {
const blob = await response.blob();
// Handle the PDF blob (e.g., download or display)
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
ملاحظات استقرار
هنگام استقرار در Vercel، این نکات را در نظر داشته باشید:
زمان اجرا: Vercel حداکثر زمان اجرای 10 ثانیه برای طرح های سرگرمی و 60 ثانیه برای طرح های حرفه ای دارد. فرآیند تولید HTML و PDF خود را بهینه کنید تا در این محدودیت ها قرار گیرد.
استفاده از حافظه: مراقب استفاده از حافظه باشید. حداقل باینری Chromium کمک می کند، اما PDF های پیچیده ممکن است همچنان از حافظه قابل توجهی استفاده کنند.
شروع سرد: عملکردهای بدون سرور می توانند شروع سرد را تجربه کنند. اولین فراخوانی ممکن است کندتر باشد زیرا باید باینری Chromium را بارگیری و راهاندازی کند.
رسیدگی به خطا: برای مدیریت وقفه ها یا محدودیت های منابع، مدیریت خطاهای قوی را اجرا کنید.
ذخیره سازی: برای کاهش بار روی عملکردهای بدون سرور خود، استراتژیهای کش را برای فایلهای PDF که اغلب تولید میشوند، در نظر بگیرید.
نتیجه گیری
این رویکرد به شما امکان می دهد با استفاده از Next.js و Puppeteer یک API تبدیل HTML به PDF قدرتمند ایجاد کنید که با محیط بدون سرور Vercel سازگار است. با اعمال اهرم @sparticuz/chromium-min و puppeteer-core، ما بر چالش های اصلی اجرای Puppeteer در زمینه بدون سرور غلبه می کنیم.
تبدیل HTML به PDF یک نیاز رایج در برنامه های کاربردی وب است. در این پست وبلاگ، نحوه ایجاد یک مسیر API Next.js را بررسی خواهیم کرد که HTML را با استفاده از Puppeteer به PDF تبدیل میکند، و مطمئن میشویم که هنگام استقرار در Vercel کار میکند.
چالش
در حالی که Puppeteer یک ابزار قدرتمند برای تبدیل HTML به PDF است، هنگام استقرار در محیطهای بدون سرور مانند Vercel با چالشهایی مواجه میشود. مسائل اصلی عبارتند از:
- Puppeteer به یک باینری Chromium نیاز دارد که از محدودیت های اندازه Vercel بیشتر است.
- توابع بدون سرور زمان و منابع محدودی برای اجرا دارند.
راه حل
ما از ترکیبی از @sparticuz/chromium-min
و puppeteer-core
برای غلبه بر این محدودیت ها در اینجا نحوه برخورد ما با آن آمده است:
- از یک ساخت حداقل کرومیوم که برای محیط های بدون سرور طراحی شده است استفاده کنید.
- Puppeteer را برای استفاده از این حداقل نسخه Chromium پیکربندی کنید.
- فرآیند تولید PDF را برای اجرای بدون سرور بهینه کنید.
مرحله 1: راه اندازی پروژه
ابتدا یک پروژه Next.js جدید ایجاد کنید یا از یک پروژه موجود استفاده کنید. سپس، وابستگی های لازم را نصب کنید:
npm install @sparticuz/chromium-min puppeteer-core
برای اطمینان از سازگاری و عملکرد بهینه، مهم است که از نسخه های صحیح بسته های مورد نیاز استفاده کنید. در آخرین آزمایش، نسخه های زیر توصیه می شود:
{
"dependencies": {
"@sparticuz/chromium-min": "^129.0.0",
"puppeteer-core": "^23.5.0"
}
}
مرحله 2: ایجاد مسیر API
ایجاد یک فایل جدید در app/api/html-to-pdf/route.js
(برای روتر برنامه Next.js 13+) یا pages/api/html-to-pdf.js
(برای روتر Pages). این هم کد:
const chromium = require("@sparticuz/chromium-min");
const puppeteer = require("puppeteer-core");
async function getBrowser() {
return puppeteer.launch({
args: [...chromium.args, "--hide-scrollbars", "--disable-web-security"],
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath(
`https://github.com/Sparticuz/chromium/releases/download/v129.0.0/chromium-v129.0.0-pack.tar`
),
headless: chromium.headless,
ignoreHTTPSErrors: true
});
}
export async function POST(request) {
try {
const { html } = await request.json();
const browser = await getBrowser();
const page = await browser.newPage();
await page.setContent(html, { waitUntil: "networkidle0" });
const pdfBuffer = await page.pdf({
format: "A4",
printBackground: true,
margin: { top: "1cm", right: "1cm", bottom: "1cm", left: "1cm" }
});
await browser.close();
return new Response(pdfBuffer, {
headers: {
"Content-Type": "application/pdf",
"Content-Disposition": 'attachment; filename="output.pdf"'
}
});
} catch (error) {
console.error("Error generating PDF:", error);
return new Response(JSON.stringify({ error: "Failed to generate PDF" }), {
status: 500,
headers: { "Content-Type": "application/json" }
});
}
}
مرحله 3: درک کد
بیایید بخش های کلیدی این کد را تجزیه کنیم:
پیکربندی مرورگر
را getBrowser
تابع Puppeteer را با حداقل باینری Chromium راه اندازی می کند:
async function getBrowser() {
return puppeteer.launch({
args: [...chromium.args, "--hide-scrollbars", "--disable-web-security"],
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath(
`https://github.com/Sparticuz/chromium/releases/download/v129.0.0/chromium-v129.0.0-pack.tar`
),
headless: chromium.headless,
ignoreHTTPSErrors: true
});
}
این پیکربندی از @sparticuz/chromium-min
بسته ای برای ارائه حداقل کروم باینری سازگار با محیط های بدون سرور.
نسل PDF
منطق اصلی برای تولید PDF در POST
تابع:
- HTML را از بدنه درخواست استخراج کنید.
- یک نمونه مرورگر را با استفاده از
getBrowser
تابع - یک صفحه جدید ایجاد کنید و محتوای آن را به HTML ارائه شده تنظیم کنید.
- یک پی دی اف از محتوای صفحه تولید کنید.
- برای آزاد کردن منابع، مرورگر را ببندید.
- PDF را به عنوان پاسخ با هدرهای مناسب برگردانید.
مرحله 4: استفاده از API
برای استفاده از این API، یک درخواست POST با محتوای HTML در بدنه درخواست ارسال کنید:
const response = await fetch('/api/html-to-pdf', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ html: '' }),
});
if (response.ok) {
const blob = await response.blob();
// Handle the PDF blob (e.g., download or display)
}
ملاحظات استقرار
هنگام استقرار در Vercel، این نکات را در نظر داشته باشید:
-
زمان اجرا: Vercel حداکثر زمان اجرای 10 ثانیه برای طرح های سرگرمی و 60 ثانیه برای طرح های حرفه ای دارد. فرآیند تولید HTML و PDF خود را بهینه کنید تا در این محدودیت ها قرار گیرد.
-
استفاده از حافظه: مراقب استفاده از حافظه باشید. حداقل باینری Chromium کمک می کند، اما PDF های پیچیده ممکن است همچنان از حافظه قابل توجهی استفاده کنند.
-
شروع سرد: عملکردهای بدون سرور می توانند شروع سرد را تجربه کنند. اولین فراخوانی ممکن است کندتر باشد زیرا باید باینری Chromium را بارگیری و راهاندازی کند.
-
رسیدگی به خطا: برای مدیریت وقفه ها یا محدودیت های منابع، مدیریت خطاهای قوی را اجرا کنید.
-
ذخیره سازی: برای کاهش بار روی عملکردهای بدون سرور خود، استراتژیهای کش را برای فایلهای PDF که اغلب تولید میشوند، در نظر بگیرید.
نتیجه گیری
این رویکرد به شما امکان می دهد با استفاده از Next.js و Puppeteer یک API تبدیل HTML به PDF قدرتمند ایجاد کنید که با محیط بدون سرور Vercel سازگار است. با اعمال اهرم @sparticuz/chromium-min
و puppeteer-core
، ما بر چالش های اصلی اجرای Puppeteer در زمینه بدون سرور غلبه می کنیم.