Bỏ qua để đến nội dung
getnextpdf.com

Pro phiên bản

Webview

Webview giao một PDF đã linearized (Fast Web View) qua HTTP để một client có thể bắt đầu kết xuất trang 1 từ một tiền tố dẫn đầu nhỏ trong khi phần còn lại của tệp vẫn đang trên đường truyền. Nó bọc các byte thô thành một LinearizedDocument, trả lời các yêu cầu Range bằng các phản hồi partial-content theo RFC 9110 qua một ByteRangeResponder PSR-7, và có thể chứng minh (qua FirstPageProber) rằng trang đầu tiên tự-chứa-đủ trong tiền tố.

Năng lực này có trong NextPDF Pro (nextpdf/pro) và kích hoạt bằng một license envelope bậc Pro. Một triển khai không có entitlement đó sẽ không nạp các lớp của năng lực này. So sánh các phiên bản và lấy giấy phép.

Không có cờ giấy phép riêng theo từng tính năng. Responder được nối với các factory PSR-17 của riêng bạn lúc chạy — một ResponseFactoryInterface và một StreamFactoryInterface — và media type mặc định là application/pdf dưới dạng một đối số constructor, không phải một công tắc giấy phép.

Terminal window
composer require nextpdf/pro

Mã nằm dưới namespace NextPDF\Pro\Webview.

Một PDF đã linearized được bố trí sao cho trang đầu tiên của tài liệu — từ điển tham số linearization, primary hint stream, và các đối tượng của trang 1 — nằm trong một phần dẫn đầu kết thúc tại offset /E. Webview biến bố cục đó thành việc giao lũy tiến.

LinearizedDocument::fromBytes() phân tích các byte qua LinearizationView ở phía-đọc của Core (Pro không bao giờ hiện thực hóa lại việc phân tích linearization) và từ chối bất kỳ thứ gì không phải là một tài liệu linearized dùng được: hoàn toàn không linearized, một độ dài /L được khai báo không khớp với độ dài byte thực, hoặc một offset kết-thúc-trang-đầu /E không phải là một offset dương bên trong tệp. Do đó việc khởi tạo là toàn phần (total) — một khi bạn nắm một LinearizedDocument, mọi offset nó phơi bày đều đáng tin.

ByteRangeResponder sau đó trả lời một yêu cầu HTTP. Nó chỉ được hiện thực dựa trên PSR-7 / PSR-17, không gắn với framework nào. Nó luôn quảng bá Accept-Ranges: bytes và một ETag SHA-256 mạnh, tất định, phân tích header Range của client theo RFC 9110 §14, và trả về hoặc một 200 OK đầy đủ, một 206 Partial Content đơn-range, một phản hồi 206 multipart/byteranges cho nhiều range, hoặc một 416 Range Not Satisfiable.

FirstPageProber là phía chứng minh cấu trúc: nó định lượng tiền tố trang-đầu, phần trăm của toàn bộ tệp mà tiền tố đó đại diện, và liệu primary hint stream có nằm hoàn toàn bên trong nó hay không — thuộc tính cho phép một bên đọc định vị các đối tượng trang-1 chỉ từ riêng tiền tố.

Webview không bao giờ tự phân tích lại linearization. Nó mượn LinearizationView ở phía-đọc của Core, nên lớp giao thừa hưởng một trình phân tích đã được kiểm định thay vì một bản sao thứ hai, dễ trôi dạt. Việc khởi tạo được cố ý làm toàn phần. LinearizedDocument::fromBytes() từ chối một bố cục dị dạng ngay từ đầu, nên mọi offset mà một phản hồi Range tin cậy đều đã được xác thực trước. Responder chỉ nói PSR-7 và PSR-17, nên cùng một đoạn mã phục vụ một PDF đã linearized từ bất kỳ HTTP stack nào. Chính sự kỷ luật đó làm cho việc giao range lũy tiến an toàn để phơi ra cho các client không đáng tin ở quy mô lớn.

Bối cảnh thiết kế: Tạo tài liệu khối lượng lớn.

Cách phục vụ byte-range lũy tiến hoạt động

Phần tiêu đề “Cách phục vụ byte-range lũy tiến hoạt động”
  1. Dựng một LinearizedDocument từ các byte PDF đã kết xuất. Đầu vào không hợp lệ làm phát sinh UnsupportedDocumentException ngay từ đầu.
  2. Trao tài liệu và ServerRequestInterface PSR-7 đến cho ByteRangeResponder::respond(). Responder đọc Range (và tiền điều kiện If-Range tùy chọn), và tạo ra ResponseInterface PSR-7 đúng đắn.
  3. Client yêu cầu tiền tố dẫn đầu trước (hoặc bạn đẩy nó với firstPageResponse()), kết xuất trang 1, rồi yêu cầu các range còn lại khi người dùng cuộn.

Mô hình byte-range dùng các offset bao gồm (inclusive) theo RFC 9110 §14.1.2: một ByteRangefirstBytelastByte trên một biểu diễn có contentLength, và trường Content-Range của nó là bytes first-last/length.

  • LinearizedDocument::fromBytes() là toàn phần: một tài liệu không-linearized, một sai lệch /L, hoặc một offset /E không-dương / ngoài-tệp mỗi cái đều làm phát sinh UnsupportedDocumentException thay vì tạo ra một tài liệu không an toàn.
  • ETag là một entity-tag SHA-256 mạnh trên các byte chính xác, được ghi nhớ một lần lúc khởi tạo. Cùng một đầu vào kết xuất cho ra cùng các byte và do đó một ETag y hệt, nên các cache và If-Range hành xử một cách có thể đoán trước.
  • Một yêu cầu không có Range áp dụng được sẽ trả về 200 OK với toàn bộ body. Một If-Range không khớp ETag mạnh hiện tại làm cho Range bị bỏ qua và một 200 đầy đủ được trả về (RFC 9110 §13.1.5). Chỉ dạng entity-tag mạnh của If-Range được tôn trọng; một If-Range dạng HTTP-date được coi là không-khớp.
  • Một đơn vị range không nhận diện được hoặc một Range sai cú pháp sẽ bị bỏ qua và một 200 đầy đủ được trả về (RFC 9110 §14.2).
  • Một range thỏa mãn được trả về 206 Partial Content với Content-Range; nhiều range thỏa mãn được trả về 206 multipart/byteranges. Các byte range hợp lệ mà không cái nào thỏa mãn được trả về 416 với Content-Range: bytes */length (RFC 9110 §15.3.7).
  • firstPageResponse() phát ra một 206 mang theo đúng byte range của trang đầu [0, /E - 1] — dạng server-push của “trang đầu trước khi tải về đầy đủ”.

Phần dưới đây phản ánh public API đã được ghi tài liệu. Kho mã không đi kèm một ví dụ có thể chạy cho module này.

use NextPDF\Pro\Webview\LinearizedDocument;
use NextPDF\Pro\Webview\ByteRangeResponder;
$document = LinearizedDocument::fromBytes($pdfBytes);
$responder = new ByteRangeResponder($responseFactory, $streamFactory);
$response = $responder->respond($document, $request);
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 đòi hỏi một PDF thực sự đã linearized. Nếu tài liệu đã kết xuất không được linearized, hãy bật linearization lúc kết xuất, hoặc phục vụ nó bằng việc giao đầy đủ thông thường — respondToBytes() vẫn có thể phục vụ các range trên các byte tùy ý (không-linearized) khi bạn chỉ cần hỗ trợ range, không cần ngữ nghĩa trang-đầu.
  • Các incremental update có vai trò quan trọng: một tài liệu đã bị thêm vào (append) vượt quá /L được khai báo của nó sẽ bị từ chối vì sai lệch độ dài, bởi các offset byte-range sẽ không còn đáng tin.
  • Responder giới hạn số lượng range riêng biệt mà nó tôn trọng cho mỗi yêu cầu. Một yêu cầu xin nhiều range đã gộp hơn giới hạn, hoặc nhiều byte tổng hơn toàn bộ biểu diễn, sẽ bị bỏ qua Range và được phục vụ một 200 đầy đủ.

Tiền tố trang-đầu là offset kết-thúc-trang-đầu /E được kẹp về độ dài tệp, nên FirstPageProber::prefixFraction() báo cáo lần fetch ban đầu nhỏ đến mức nào so với toàn bộ tệp — với một tài liệu nhiều trang đây là toàn bộ ý nghĩa của Fast Web View. Việc dựng phản hồi cắt lát chuỗi byte trong bộ nhớ; chi phí tỉ lệ với các byte được chọn. ETag được tính một lần cho mỗi tài liệu. Hãy đo bằng các tài liệu đại diện.

Hãy coi đầu vào là không đáng tin. LinearizedDocument::fromBytes() xác thực các bất biến linearization trước khi bất kỳ offset nào được dùng. Responder từ chối một contentType chứa ký tự điều khiển để ngăn header injection, suy ra một biên multipart được đảm bảo không xuất hiện bên trong body, và gộp các range chồng lấn rồi giới hạn số lượng cùng kích thước tổng của chúng để phòng thủ trước lớp tấn công từ chối dịch vụ kiểu khuếch-đại-range-multipart (Apache HTTPD CVE-2011-3192). Module này không ghi nhật ký nội dung tài liệu nào.

Việc giao byte-range tuân theo RFC 9110 (HTTP Semantics) — §14 cho các yêu cầu range, §13.1.5 cho If-Range, và §15.3.7 cho 416. Mô hình tài-liệu-linearized là bố cục Fast Web View được mô tả bởi ISO 32000-2 Annex F. Module không khẳng định thêm định danh điều khoản bên ngoài nào ngoài hành vi đã được các test của nó kiểm chứng.

Enterprise không thay đổi hành vi của Webview. Enterprise bổ sung các tính năng phù hợp và lưu trữ bậc cao hơn được ghi tài liệu riêng; chúng không bắt buộc để phục vụ một PDF đã linearized qua các byte range.

Trang này chỉ ghi tài liệu về hành vi quan sát được từ bên ngoài và bề mặt public API được hỗ trợ. Các đường dẫn namespace nội bộ, các lớp trợ giúp, các bảng cơ chế, các tên tệp runbook, và các tiền tố ticket đều nằm ngoài phạm vi.