Przejdź do głównej zawartości
getnextpdf.com

Pro edycja

Webview

Webview dostarcza zlinearyzowany (Fast Web View) plik PDF przez HTTP, więc klient może zacząć renderować stronę 1 z niewielkiego wiodącego prefiksu, podczas gdy reszta pliku jest jeszcze w drodze. Opakowuje surowe bajty jako LinearizedDocument, odpowiada na żądania Range odpowiedziami partial-content zgodnymi z RFC 9110 przez ByteRangeResponder w PSR-7 i potrafi udowodnić (przez FirstPageProber), że pierwsza strona jest samowystarczalna w prefiksie.

Ta funkcja jest dostarczana w NextPDF Pro (nextpdf/pro) i aktywuje się z kopertą licencyjną poziomu Pro. Wdrożenie bez tego uprawnienia nie ładuje klas tej funkcji. Porównaj edycje i uzyskaj licencję.

Nie istnieje osobna flaga licencji na poziomie pojedynczej funkcji. Responder jest podłączany do Twoich własnych fabryk PSR-17 w czasie działania — ResponseFactoryInterface i StreamFactoryInterface — a typ media domyślnie wynosi application/pdf jako argument konstruktora, a nie przełącznik licencji.

Okno terminala
composer require nextpdf/pro

Kod znajduje się w przestrzeni nazw NextPDF\Pro\Webview.

Zlinearyzowany PDF jest rozplanowany tak, aby pierwsza strona dokumentu — słownik parametrów linearyzacji, główny strumień podpowiedzi (hint stream) oraz obiekty strony 1 — znalazła się w wiodącej sekcji kończącej się na przesunięciu /E. Webview zamienia ten układ w dostarczanie progresywne.

LinearizedDocument::fromBytes() parsuje bajty przez odczytową LinearizationView z Core (Pro nigdy nie reimplementuje parsowania linearyzacji) i odrzuca wszystko, co nie jest użytecznym zlinearyzowanym dokumentem: w ogóle niezlinearyzowanym, z zadeklarowaną długością /L, która nie pasuje do rzeczywistej długości bajtów, lub z przesunięciem końca pierwszej strony /E, które nie jest dodatnim przesunięciem wewnątrz pliku. Konstrukcja jest zatem całkowita — gdy już dysponujesz LinearizedDocument, każde udostępniane przez niego przesunięcie jest wiarygodne.

ByteRangeResponder następnie odpowiada na żądanie HTTP. Jest zaimplementowany wyłącznie względem PSR-7 / PSR-17, bez powiązania z frameworkiem. Zawsze ogłasza Accept-Ranges: bytes oraz silny, deterministyczny ETag SHA-256, parsuje nagłówek Range klienta zgodnie z RFC 9110 §14 i zwraca albo pełne 200 OK, albo pojedynczy zakres 206 Partial Content, albo odpowiedź 206 multipart/byteranges dla kilku zakresów, albo 416 Range Not Satisfiable.

FirstPageProber to strona dowodu strukturalnego: kwantyfikuje prefiks pierwszej strony, ułamek całego pliku, który ten prefiks reprezentuje, oraz to, czy główny strumień podpowiedzi leży w całości wewnątrz niego — właściwość, która pozwala czytnikowi zlokalizować obiekty strony 1 z samego prefiksu.

Webview nigdy sam nie parsuje ponownie linearyzacji. Zapożycza odczytową LinearizationView z Core, więc warstwa dostarczania dziedziczy jeden audytowany parser zamiast drugiej, rozjeżdżającej się kopii. Konstrukcja jest celowo całkowita. LinearizedDocument::fromBytes() z góry odrzuca nieprawidłowy układ, więc każde przesunięcie, któremu ufa odpowiedź Range, zostało najpierw zwalidowane. Responder mówi wyłącznie w PSR-7 i PSR-17, więc ten sam kod serwuje zlinearyzowany PDF z dowolnego stosu HTTP. To właśnie ta dyscyplina sprawia, że progresywne dostarczanie zakresów można bezpiecznie udostępniać niezaufanym klientom na dużą skalę.

Kontekst projektowy: Generowanie dokumentów o dużej objętości.

  1. Zbuduj LinearizedDocument z wyrenderowanych bajtów PDF. Nieprawidłowe dane wejściowe od razu zgłaszają UnsupportedDocumentException.
  2. Przekaż dokument oraz przychodzące ServerRequestInterface PSR-7 do ByteRangeResponder::respond(). Responder odczytuje Range (oraz opcjonalny warunek wstępny If-Range) i produkuje poprawne ResponseInterface PSR-7.
  3. Klient najpierw żąda wiodącego prefiksu (lub wypychasz go za pomocą firstPageResponse()), renderuje stronę 1, a następnie żąda pozostałych zakresów w miarę przewijania przez użytkownika.

Model zakresów bajtów używa przesunięć inkluzywnych zgodnie z RFC 9110 §14.1.2: ByteRange to firstBytelastByte w reprezentacji o contentLength, a jego pole Content-Range to bytes first-last/length.

  • LinearizedDocument::fromBytes() jest całkowite: dokument niezlinearyzowany, niezgodność /L lub niedodatnie / wykraczające poza plik przesunięcie /E zgłaszają każde UnsupportedDocumentException, zamiast wytworzyć niebezpieczny dokument.
  • ETag to silny entity-tag SHA-256 nad dokładnymi bajtami, memoizowany raz przy konstrukcji. Identyczne dane wejściowe renderowania dają identyczne bajty, a więc identyczny ETag, więc pamięci podręczne oraz If-Range zachowują się przewidywalnie.
  • Żądanie bez stosowalnego Range zwraca 200 OK z pełnym ciałem. If-Range, który nie pasuje do bieżącego silnego ETag, powoduje zignorowanie Range i zwrócenie pełnego 200 (RFC 9110 §13.1.5). Honorowana jest wyłącznie forma silnego entity-tag dla If-Range; If-Range w postaci daty HTTP jest traktowany jako brak dopasowania.
  • Nierozpoznana jednostka zakresu lub składniowo nieprawidłowy Range jest ignorowany i zwracane jest pełne 200 (RFC 9110 §14.2).
  • Jeden spełnialny zakres zwraca 206 Partial Content z Content-Range; wiele spełnialnych zakresów zwraca 206 multipart/byteranges. Prawidłowe zakresy bajtów, z których żaden nie jest spełnialny, zwracają 416 z Content-Range: bytes */length (RFC 9110 §15.3.7).
  • firstPageResponse() emituje 206 niosące dokładnie zakres bajtów pierwszej strony [0, /E - 1] — forma server-push „pierwsza strona przed pełnym pobraniem”.

Poniższe odzwierciedla udokumentowane publiczne API. Repozytorium nie dostarcza uruchamialnego przykładu dla tego modułu.

use NextPDF\Pro\Webview\LinearizedDocument;
use NextPDF\Pro\Webview\ByteRangeResponder;
$document = LinearizedDocument::fromBytes($pdfBytes);
$responder = new ByteRangeResponder($responseFactory, $streamFactory);
$response = $responder->respond($document, $request);

Przykład kodu — Wypychanie i sondowanie pierwszej strony

Dział zatytułowany „Przykład kodu — Wypychanie i sondowanie pierwszej strony”
use NextPDF\Pro\Webview\LinearizedDocument;
use NextPDF\Pro\Webview\ByteRangeResponder;
use NextPDF\Pro\Webview\FirstPageProber;
use NextPDF\Pro\Webview\Exception\UnsupportedDocumentException;
try {
$document = LinearizedDocument::fromBytes($pdfBytes);
} catch (UnsupportedDocumentException $e) {
// Not a usable linearized document — fall back to plain full delivery.
// ...
return;
}
$prober = new FirstPageProber($document);
if ($prober->isFirstPageSelfContained()) {
// Push exactly the first page's bytes for an instant render.
$response = (new ByteRangeResponder($responseFactory, $streamFactory))
->firstPageResponse($document);
}
  • Webview wymaga prawdziwie zlinearyzowanego PDF. Jeśli wyrenderowany dokument nie jest zlinearyzowany, włącz linearyzację w czasie renderowania lub serwuj go zwykłym pełnym dostarczaniem — respondToBytes() nadal potrafi serwować zakresy nad dowolnymi (niezlinearyzowanymi) bajtami, gdy potrzebujesz tylko obsługi zakresów, a nie semantyki pierwszej strony.
  • Aktualizacje przyrostowe mają znaczenie: dokument, do którego dopisano dane poza jego zadeklarowanym /L, jest odrzucany jako niezgodność długości, ponieważ przesunięcia zakresów bajtów przestałyby być wiarygodne.
  • Responder ogranicza liczbę odrębnych zakresów, które honoruje na żądanie. Żądanie o więcej scalonych zakresów niż limit, lub o więcej łącznych bajtów niż cała reprezentacja, ma swój Range zignorowany i jest obsługiwane pełnym 200.

Prefiks pierwszej strony to przesunięcie końca pierwszej strony /E przycięte do długości pliku, więc FirstPageProber::prefixFraction() raportuje, jak małe jest początkowe pobranie względem całego pliku — dla dokumentu wielostronicowego to cały sens Fast Web View. Budowanie odpowiedzi wycina łańcuch bajtów z pamięci; koszt jest proporcjonalny do wybranych bajtów. ETag jest obliczany raz na dokument. Mierz na reprezentatywnych dokumentach.

Traktuj dane wejściowe jako niezaufane. LinearizedDocument::fromBytes() waliduje niezmienniki linearyzacji przed użyciem jakiegokolwiek przesunięcia. Responder odrzuca contentType zawierający znaki sterujące, aby zapobiec wstrzyknięciu nagłówka, wyprowadza granicę multipart, która z gwarancją nie wystąpi wewnątrz ciała, oraz scala nakładające się zakresy i ogranicza ich liczbę i łączny rozmiar, aby bronić się przed klasą ataków odmowy usługi typu multipart range-amplification (Apache HTTPD CVE-2011-3192). Ten moduł nie loguje żadnej treści dokumentu.

Dostarczanie zakresów bajtów jest zgodne z RFC 9110 (HTTP Semantics) — §14 dla żądań zakresów, §13.1.5 dla If-Range oraz §15.3.7 dla 416. Model zlinearyzowanego dokumentu to układ Fast Web View opisany w ISO 32000-2 Annex F. Moduł nie deklaruje żadnych dalszych zewnętrznych identyfikatorów klauzul poza zachowaniem zweryfikowanym jego testami.

Enterprise nie zmienia zachowania Webview. Enterprise dodaje funkcje zgodności i archiwizacji wyższego poziomu, udokumentowane osobno; nie są one wymagane do serwowania zlinearyzowanego PDF przez zakresy bajtów.

Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie oraz wspieraną publiczną powierzchnię API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tabele mechanizmów, nazwy plików runbooków oraz prefiksy zgłoszeń są poza zakresem.