PORóWNANIE

wkhtmltopdf vs IronPDF: Przewodnik porównania technicznego

Gdy programiści .NET muszą konwertować HTML na PDF,wkhtmltopdfod dawna jest popularnym wyborem ze względu na swój charakter open source i prostotę obsługi z wiersza poleceń. Jednak porzucenie projektu i krytyczne luki w zabezpieczeniach skłoniły wiele zespołów do rozważenia nowoczesnych alternatyw. W niniejszym porównaniu technicznym przeanalizowanowkhtmltopdforaz IronPDF, aby pomóc architektom i programistom zrozumieć istotne różnice w zakresie bezpieczeństwa, możliwości renderowania oraz długoterminowej użyteczności.

Zrozumienie wkhtmltopdf

wkhtmltopdf to narzędzie, które konwertuje dokumenty HTML na PDF, działające bezpośrednio z wiersza poleceń i wykorzystujące Qt WebKit do przetwarzania treści HTML. W ciągu lat aktywnego rozwoju biblioteka zyskała popularność dzięki bezpłatnej licencji LGPLv3 i dostępności na wielu platformach.

Jednakwkhtmltopdfstwarza obecnie poważne wyzwania, których nie można zignorować:

  • Zaniechanie projektu: Ostatnie znaczące aktualizacje oprogramowania miały miejsce około 2016–2017 roku
  • Krytyczna luka w zabezpieczeniach: CVE-2022-35583 (poziom zagrożenia CVSS 9,8) to luka SSRF, która pozostaje niezałatana
  • Przestarzały silnik renderujący: oparty na Qt WebKit z 2015 roku
  • Ograniczona obsługa nowoczesnych technologii internetowych: brak obsługi CSS Grid, nieprawidłowa implementacja Flexbox, brak obsługi JavaScript ES6+
  • Stagnacja ekosystemu: Wszystkie biblioteki opakowujące .NET (DinkToPdf, Rotativa, TuesPechkin, WkHtmlToPdf-DotNet, NReco.PdfGenerator) dziedziczą te luki w zabezpieczeniach

Kryzys bezpieczeństwa CVE-2022-35583

Luka w zabezpieczeniach typu Server-Side Request Forgery (SSRF) wwkhtmltopdfpozwala atakującym na:

  • Dostęp do usług wewnętrznych: Dostęp do wewnętrznych interfejsów API, baz danych i usług znajdujących się za zaporami sieciowymi
  • Kradzież danych uwierzytelniających: Uzyskaj dostęp do punktów końcowych metadanych w chmurze (AWS, GCP, Azure) w celu kradzieży danych uwierzytelniających IAM
  • Skanowanie portów: Skanowanie sieci wewnętrznych z poziomu infrastruktury
  • Wyciek danych: Wyodrębnianie poufnych danych za pomocą spreparowanego kodu HTML/CSS

Wektor ataku jest prosty — złośliwy kod HTML przesłany do generatora plików PDF:


<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>

<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>
HTML

Kiedywkhtmltopdfrenderuje ten kod HTML, pobiera te adresy URL z kontekstu sieciowego serwera, omijając zapory sieciowe i zabezpieczenia. Ta luka w zabezpieczeniach nigdy nie zostanie załatana, ponieważ projekt został oficjalnie porzucony.

Zrozumienie IronPDF

IronPDF stanowi solidną alternatywę, która rozwiązuje niedociągnięcia wkhtmltopdf. Dzięki aktywnej konserwacji, regularnym aktualizacjom i wykorzystaniu najnowszego silnika renderującego Chromium, IronPDF zapewnia zarówno bezpieczeństwo, jak i zgodność z nowoczesnymi standardami internetowymi.

Kluczowe cechy obejmują:

  • Nowoczesny silnik Chromium: Wykorzystuje aktualny silnik renderujący Chromium z pełną obsługą JavaScript ES2024
  • Brak znanych luk CVE: Zero znanych luk w zabezpieczeniach
  • Aktywny rozwój: Regularne wydania zawierające aktualizacje zabezpieczeń i ulepszenia funkcji
  • Pełna obsługa CSS: pełna obsługa CSS Grid, Flexbox i nowoczesnych systemów układów
  • Kompleksowe funkcje PDF: podpisy cyfrowe, zgodność z PDF/A, możliwości edycji plików PDF
  • Profesjonalne wsparcie: Obszerna dokumentacja i dedykowane kanały wsparcia

Porównanie funkcji

Poniższa tabela przedstawia podstawowe różnice międzywkhtmltopdfa IronPDF:

Funkcja wkhtmltopdf IronPDF
Licencjonowanie LGPLv3 (bezpłatna) Komercjalne
Silnik renderujący Qt WebKit (2015) Aktualny silnik Chromium
Stan bezpieczeństwa CVE-2022-35583 KRYTYCZNE (9,8) BEZ ŁATKI Brak znanych luk CVE
Ostatnia znacząca aktualizacja 2016-2017 Aktywny rozwój
CSS Grid Nieobsługiwane Obsługiwane
Flexbox Uszkodzone Obsługiwane
JavaScript ES6+ Nieobsługiwane Obsługiwane
Async/Await Nieobsługiwane Obsługiwane
Manipulacja plikami PDF Nieobsługiwane Obsługiwane
Podpisy cyfrowe Nieobsługiwane Obsługiwane
Zgodność z PDF/A Nieobsługiwane Obsługiwane
Profesjonalne wsparcie Brak (porzucone) Reklama z umową SLA
Integracja z C# Za pośrednictwem nakładek innych firm Bezpośredni, regularnie aktualizowany

Biblioteki opakowujące, których to dotyczy

Wszystkie nakładki .NET dlawkhtmltopdfdziedziczą te same luki w zabezpieczeniach:

Biblioteka opakowująca Status Zagrożenie bezpieczeństwa
DinkToPdf Porzucony KLUCZOWE
Rotativa Porzucony KLUCZOWE
TuesPechkin Porzucony KLUCZOWE
WkHtmlToPdf-DotNet Porzucony KLUCZOWE
NReco.PdfGenerator Wykorzystujewkhtmltopdf KLUCZOWE

Jeśli Twoja aplikacja korzysta z którejkolwiek z tych bibliotek, jest podatna na lukę CVE-2022-35583.

Różnice w architekturze API

Wzorce API między opakowaniamiwkhtmltopdfaIronPDFujawniają znaczące różnice w złożoności i użyteczności.

Wzorzec konfiguracji wkhtmltopdf

Owijkiwkhtmltopdfwymagają tworzenia obiektów dokumentów z zagnieżdżonymi konfiguracjami ustawień:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("output.pdf", pdf)
    End Sub
End Class
$vbLabelText   $csharpLabel

Ten wzorzec wymaga utworzenia SynchronizedConverter z PdfTools, skonstruowania HtmlToPdfDocument z kolekcjami GlobalSettings i Objects oraz ręcznego zapisu tablic bajtów do plików.

Uproszczony wzór IronPDF

IronPDF używa uproszczonego podejścia z klasą ChromePdfRenderer:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Klasa ChromePdfRenderer eliminuje zagnieżdżone obiekty konfiguracyjne, zwracając PdfDocument z wbudowanymi metodami zapisu. Aby uzyskać wyczerpujące wskazówki dotyczące konwersji HTML, zapoznaj się z samouczkiem dotyczącym konwersji HTML do PDF.

Konwersja adresów URL do formatu PDF

Konwersja stron internetowych do formatu PDF pokazuje różnicę w złożoności tych podejść.

Wdrożenie wkhtmltopdf

wkhtmltopdf używa właściwości Page w ramach ObjectSettings do określania URLi:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "https://www.example.com"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "https://www.example.com"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "https://www.example.com"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("webpage.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

Wdrożenie IronPDF

IronPDF zapewnia dedykowaną metodę RenderUrlAsPdf:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Metoda RenderUrlAsPdf wykorzystuje silnik Chromium do renderowania stron z pełnym wykonaniem JavaScript i obsługą nowoczesnego CSS — możliwości ograniczone przez silnik WebKitwkhtmltopdfz 2015 roku.

Niestandardowe ustawienia plików PDF

Konfiguracja wymiarów strony, marginesów i orientacji ujawnia różnice strukturalne między interfejsami API.

Ustawienia niestandardowe wkhtmltopdf

wkhtmltopdf wymaga zagnieżdżonych GlobalSettings z obiektami MarginSettings:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Landscape,
                .PaperSize = PaperKind.A4,
                .Margins = New MarginSettings() With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "input.html",
                    .WebSettings = New WebSettings() With {.DefaultEncoding = "utf-8"}
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("custom-output.pdf", pdf)
    End Sub
End Class
$vbLabelText   $csharpLabel

Ustawienia niestandardowe IronPDF

IronPDF używa właściwości RenderingOptions do bezpośredniej konfiguracji:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Class Program
    Shared Sub Main()
        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10
        renderer.RenderingOptions.MarginLeft = 10
        renderer.RenderingOptions.MarginRight = 10
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4

        Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
        pdf.SaveAs("custom-output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Przewodnik po mapowaniu API

Zespoły rozważające przejście zwkhtmltopdfnaIronPDFuznają to mapowanie za pomocne w zrozumieniuiuiuiuiu równoważności pojęć:

Mapowanie CLI do API C

Opcja CLIwkhtmltopdf OdpowiednikIronPDF
wkhtmltopdf input.html output.pdf renderer.RenderHtmlFileAsPdf()
wkhtmltopdf URL output.pdf renderer.RenderUrlAsPdf()
--page-size A4 RenderingOptions.PaperSize = PdfPaperSize.A4
--page-size Letter RenderingOptions.PaperSize = PdfPaperSize.Letter
--orientation Landscape RenderingOptions.PaperOrientation = Landscape
--margin-top 10mm RenderingOptions.MarginTop = 10
--margin-bottom 10mm RenderingOptions.MarginBottom = 10
--margin-left 10mm RenderingOptions.MarginLeft = 10
--margin-right 10mm RenderingOptions.MarginRight = 10
--header-html header.html RenderingOptions.HtmlHeader
--footer-html footer.html RenderingOptions.HtmlFooter
--footer-center "[page]" {page} placeholder
--footer-center "[toPage]" {total-pages} placeholder
--enable-javascript Włączone domyślnie
--javascript-delay 500 RenderingOptions.WaitFor.RenderDelay = 500
--print-media-type RenderingOptions.CssMediaType = Print
--dpi 300 RenderingOptions.Dpi = 300
--grayscałe RenderingOptions.GrayScałe = true
--zoom 0.8 RenderingOptions.Zoom = 80

Mapowanie API opakowania C

wkhtmltopdf Wrapper IronPDF
SynchronizedConverter ChromePdfRenderer
HtmlToPdfDocument RenderingOptions
GlobalSettings.Out pdf.SaveAs()
GlobalSettings.PaperSize RenderingOptions.PaperSize
GlobalSettings.Orientation RenderingOptions.PaperOrientation
GlobalSettings.Margins RenderingOptions.Margin*
ObjectSettings.Page RenderHtmlFileAsPdf()
ObjectSettings.HtmlContent RenderHtmlAsPdf()
HeaderSettings.Center TextHeader.CenterText
FooterSettings.Center TextFooter.CenterText
converter.Convert(doc) renderer.RenderHtmlAsPdf()

Mapowanie składni symboli zastępczych

wkhtmltopdfMiejsce na tekst IronPDF Placeholder
[page] {page}
[toPage] {total-pages}
[date] {date}
[time] {time}
[title] {html-title}
[url] {url}

Kiedy zespoły rozważają przejście zwkhtmltopdfna IronPDF

Istnieje kilka scenariuszy, w których zespoły programistów często rozważająIronPDFjako alternatywę dla wkhtmltopdf:

Wymagania dotyczące zgodności z przepisami bezpieczeństwa

Organizacje, które muszą spełniać wymogi dotyczące zgodności z normami bezpieczeństwa (SOC 2, PCI DSS, HIPAA), nie mogą akceptować aplikacji zawierających znane krytyczne luki w zabezpieczeniach. Ocena ważności CVE-2022-35583 na poziomie 9,8 powoduje konieczność natychmiastowego podjęcia działań naprawczych w większości systemów bezpieczeństwa.

Wdrażanie nowoczesnych frameworków CSS

Zespoły korzystające z Bootstrap 5, Tailwind CSS lub niestandardowych układów CSS Grid zauważają, żewkhtmltopdfnie wyświetla ich poprawnie. Silnik WebKit z 2015 r. całkowicie nie obsługuje CSS Grid i ma wadliwą implementację Flexbox.

Wymagania dotyczące aplikacji JavaScript

Aplikacje korzystające z nowoczesnych funkcji JavaScript — składni ES6+, w tym funkcji strzałkowych, async/await, klas i literałów szablonowych — napotykają błędy w wkhtmltopdf. Silnik Chromium firmyIronPDFzapewnia pełną obsługę języka JavaScript.

Wdrożenia w chmurze i kontenerach

Nowoczesne strategie wdrażania wykorzystujące Docker, Kubernetes lub platformy chmurowe czerpią korzyści z architekturyIronPDFdostosowanej do kontenerów. Skanowanie bezpieczeństwa plików binarnychwkhtmltopdfw kontenerach wskaże lukę CVE.

Kwestie związane z długoterminową konserwacją

Ponieważ nie przewiduje się przyszłych aktualizacji wkhtmltopdf, zespoły borykają się z rosnącym długiem technicznym w miarę ewolucji standardów internetowych. Aktywny rozwójIronPDFzapewnia ciągłą kompatybilność z przyszłymi wersjami .NET, w tym z .NET 10, którego premiera przewidziana jest na 2026 rok.

Dodatkowe możliwości IronPDF

Oprócz konwersji HTML do PDF,IronPDFoferuje funkcje edycji dokumentów, którychwkhtmltopdfnie jest w stanie zapewnić:

Obsługa asynchroniczna

IronPDF zapewnia obsługę async/await w celu poprawy wydajności aplikacji internetowych:

public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
Imports System.Threading.Tasks

Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
    Dim renderer As New ChromePdfRenderer()
    Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
    Return pdf.BinaryData
End Function
$vbLabelText   $csharpLabel

Zapobiega to blokowaniu wątków w aplikacjach internetowych o dużym obciążeniu — funkcja niedostępna w przypadku wyłącznie synchronicznych opakowań wkhtmltopdf.

Zgodność z platformą .NET i gotowość na przyszłość

Zaprzestanie wsparcia dlawkhtmltopdfoznacza brak testów kompatybilności i aktualizacji dla nowszych wersji .NET.IronPDFjest aktywnie rozwijany i regularnie aktualizowany, co zapewnia kompatybilność z .NET 8, .NET 9 oraz przyszłymi wersjami, w tym .NET 10, którego premiera przewidziana jest na 2026 rok. Obsługa async/await w całym API biblioteki jest zgodna z nowoczesnymi praktykami programistycznymi w języku C#, w tym z funkcjami przewidzianymi w C# 14.

Wnioski

Różnice międzywkhtmltopdfaIronPDFsą znaczące w zakresie bezpieczeństwa, możliwości renderowania i długoterminowej użyteczności. Krytyczna luka SSRF wwkhtmltopdf(CVE-2022-35583) w połączeniu z porzuceniem projektu stwarza nie do utrzymania sytuację bezpieczeństwa dla aplikacji produkcyjnych. Silnik WebKit z 2015 roku nie obsługuje nowoczesnego CSS Grid, ma uszkodzoną obsługę Flexbox i nie działa z JavaScriptem ES6+.

Silnik renderującyIronPDFoparty na Chromium zapewnia pełną obsługę nowoczesnych standardów internetowych, nie zawierając przy tym żadnych znanych luk CVE. Jego uproszczony design API—metody jak RenderHtmlAsPdf() i SaveAs() zamiast zagnieżdżonych obiektów konfiguracyjnych—zmniejsza złożoność kodu, dodając jednocześnie możliwości takie jak manipulacja PDF, cyfrowe podpisy i wsparcie dla asynchroniczności, którewkhtmltopdfnie może zapewnić.

W przypadku zespołów korzystających obecnie zwkhtmltopdflub bibliotek opakowujących (DinkToPdf, Rotativa, TuesPechkin) konsekwencje dla bezpieczeństwa wymagają natychmiastowej oceny alternatywnych rozwiązań. Mapowanie API między opcjami wierszowego interfejsuwkhtmltopdfa opcjami RenderingOptions wIronPDFjest proste, aIronPDFkonsekwentnie wymaga mniejszego nakładu kodu, eliminując jednocześnie zagrożenia bezpieczeństwa związane z wkhtmltopdf.

Aby uzyskać dodatkowe wskazówki dotyczące wdrażania, zapoznaj się z dokumentacją IronPDF oraz samouczkami obejmującymi konkretne przypadki użycia i zaawansowane funkcje.