
우리 조직에서는 웹 페이지를 PDF로 변환하기 위해 headless-chrome을 사용합니다. 이를 위해 Chrome 인스턴스를 시작하고 통신하기 위해 다음 CDT 클라이언트를 사용하는 특수 Java 애플리케이션이 있습니다.https://github.com/kklisura/chrome-devtools-java-client 대부분의 경우 모든 것이 예상대로 작동하고 PDF를 얻지만 일부 웹 페이지의 경우 headless-chrome이 PDF 인쇄 단계 중에 중단됩니다. 해당 페이지의 예:
https://www.idc.com/cee/events/64662-web-developers-event-for-automatic-tests-on-idc-com-do-not-update-manually/print-agenda
여기에 지정된 모든 필수 단계를 따랐음에도 불구하고 헤드리스 크롬 인스턴스에서 유용한 로그를 얻을 수 없었습니다.https://www.chromium.org/for-testers/enable-logging --remote-debugging-port 옵션을 사용하여 헤드리스 인스턴스를 디버깅하려고 시도했지만 콘솔이나 다른 곳에서는 의심스러운 것을 발견하지 못했습니다. 페이지가 성공적으로 로드된 것으로 나타났으며 크롬이 페이지 인쇄를 거부한 것 같습니다.
다른 사람도 비슷한 문제를 겪었나요? 아니면 왜 이런 일이 발생하는지 아는 사람이 있을까요? 헤드리스 크롬 인스턴스에서 로깅을 활성화하는 방법에 대한 팁이 있는 사람이 있을까요? 어떤 도움이라도 감사하겠습니다.
애플리케이션 버전은 다음과 같습니다.
Google Chrome: 76.0.3809.100
chrome-devtools-java-client: 1.3.5
감사해요! 최대.
답변1
이 문제는 기본 websocket API 구현인 Tyrus로 인해 발생합니다. 그것은기본 최대 메시지 크기는 4MB입니다.. 이 URL과 기타 여러 URL(특히 인쇄 배경을 활성화하는 경우)로 인해 PDF가(base 64로 인코딩된 경우) 4MB 제한보다 커집니다. 이 경우 웹소켓은 다음과 같이 닫힙니다.버퍼 오버플로 오류그러나 우리는 그것을 다음과 같이 보지 않습니다.chrome-devtools-java-client
onClose
웹소켓의 이벤트를 듣지 않습니다.
대신 인쇄 결과를 스트리밍하여 이 문제를 해결할 수 있습니다...
PrintToPDFTransferMode.RETURN_AS_STREAM
as를 transferMode
매개변수로 전달한 Page.printToPdf
다음 4MB 제한보다 훨씬 작은 버퍼를 사용하여 스트림에서 읽습니다(기본 64로 인해 증가한 후에도). 나는 1MB를 사용한다:
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());
offset
결과가 베이스 64로 인코딩되지 않은 경우의 처리 방법은 잘 모르겠지만 인쇄할 때 이를 볼 수는 없을 것 같습니다!