Headless Chrome hängt beim Versuch, eine Seite als PDF zu drucken

Headless Chrome hängt beim Versuch, eine Seite als PDF zu drucken

In unserer Organisation verwenden wir Headless-Chrome zum Konvertieren von Webseiten in PDFs. Wir haben dafür eine spezielle Java-Anwendung, die den folgenden CDT-Client zum Starten der Chrome-Instanzen und zur Kommunikation mit ihnen verwendet:https://github.com/kklisura/chrome-devtools-java-client In den meisten Fällen funktioniert alles wie erwartet und wir erhalten unsere PDFs, aber bei einigen Webseiten bleibt headless-chrome beim PDF-Drucken einfach hängen. Beispiel für eine solche Seite:

https://www.idc.com/cee/events/64662-web-developers-event-for-automatic-tests-on-idc-com-do-not-update-manually/print-agenda

Wir konnten keine nützlichen Protokolle von den Headless-Instanzen von Chrome abrufen, obwohl wir alle hier angegebenen erforderlichen Schritte befolgt haben:https://www.chromium.org/for-testers/enable-logging Wir haben versucht, diese Headless-Instanzen mit der Option --remote-debugging-port zu debuggen, aber wir haben weder in der Konsole noch sonst irgendwo etwas Verdächtiges gefunden. Die Seite schien erfolgreich geladen worden zu sein und es scheint, dass Chrome sich einfach geweigert hat, die Seiten zu drucken.

Hatte jemand anderes ähnliche Probleme? Oder hat vielleicht jemand eine Idee, warum das passiert? Vielleicht hat jemand Tipps, wie man die Protokollierung in den Headless-Instanzen von Chrome aktiviert? Wir sind für jede Hilfe dankbar.

Hier sind die Versionen der Anwendungen:

Google Chrome: 76.0.3809.100
chrome-devtools-java-client: 1.3.5

Danke! Max.

Antwort1

Dieses Problem wird durch die zugrunde liegende WebSocket-API-Implementierung Tyrus verursacht. Es hat eineStandardmäßige maximale Nachrichtengröße von 4 MB. Diese URL und viele andere (insbesondere wenn Sie das Drucken von Hintergründen aktivieren) führen zu PDFs, die (bei Kodierung als Base 64) größer als die 4-MB-Grenze sind. In diesem Fall wird der WebSocket mit einemPufferüberlauffehler, aber wir sehen es nicht alschrome-devtools-java-client hört nicht auf die onCloseEreignisse des WebSockets.

Sie können dieses Problem lösen, indem Sie stattdessen das Druckergebnis streamen ...

Übergeben Sie dies PrintToPDFTransferMode.RETURN_AS_STREAMals transferModeParameter Page.printToPdfund lesen Sie dann aus dem Stream mit einem Puffer, der deutlich kleiner ist als das 4-MB-Limit (selbst nach der Erhöhung durch Base 64). Ich verwende 1 MB:

private static final int READ_BUFFER_SIZE = 1048576;
final PrintToPDF printToPDF = page.printToPDF(..., PrintToPDFTransferMode.RETURN_AS_STREAM);

final IO io = devToolsService.getIO();
int offset = 0;
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
    do {
        final Read read = io.read(printToPDF.getStream(), offset, READ_BUFFER_SIZE);
        if (read.getBase64Encoded() == Boolean.TRUE) {
            byte[] decode = Base64.getDecoder().decode(read.getData());
            offset += decode.length;
            fos.write(decode);
        } else {
            byte[] decode = read.getData().getBytes(StandardCharsets.UTF_8);
            offset += decode.length;
            fos.write(decode);
        }

        if (read.getEof() == Boolean.TRUE) {
            break;
        }
    } while (true);
}
io.close(printToPDF.getStream());

Ich bin mir nicht sicher, wie es offsetmit dem Ergebnis aussieht, wenn es nicht Base64-codiert ist, aber ich glaube nicht, dass wir das beim Drucken sehen werden!

verwandte Informationen