Skip to content

HTTP 响应

PdfResponse 类提供安全且符合标准的 HTTP 响应辅助,将 PDF 传递至浏览器。它自动设置所有必要的标头,包括防止 MIME 嗅探和敏感文件缓存的安全标头。

php
use Yeeefang\TcpdfNext\Laravel\Http\PdfResponse;

内嵌显示

在浏览器内置的查看器中直接呈现 PDF:

php
use Yeeefang\TcpdfNext\Laravel\Facades\Pdf;
use Yeeefang\TcpdfNext\Laravel\Http\PdfResponse;

public function preview(Invoice $invoice)
{
    $pdf = Pdf::create()
        ->setTitle("发票 #{$invoice->number}")
        ->addPage()
        ->setFont('Helvetica', '', 12)
        ->cell(0, 10, "发票 #{$invoice->number}");

    return PdfResponse::inline($pdf, "invoice-{$invoice->number}.pdf");
}

响应设置 Content-Disposition: inline,指示浏览器显示 PDF 而非触发文件下载。

强制下载

强制浏览器将 PDF 保存为文件:

php
public function download(Invoice $invoice)
{
    $pdf = Pdf::create()
        ->setTitle("发票 #{$invoice->number}")
        ->addPage()
        ->setFont('Helvetica', '', 12)
        ->cell(0, 10, "发票 #{$invoice->number}");

    return PdfResponse::download($pdf, "invoice-{$invoice->number}.pdf");
}

响应设置 Content-Disposition: attachment,触发浏览器的保存文件对话框。

安全标头

inline()download() 皆自动包含以下安全标头:

标头用途
Content-Typeapplication/pdf正确的 MIME 类型
Content-Dispositioninlineattachment显示模式
X-Content-Type-Optionsnosniff防止 MIME 嗅探攻击
Cache-Controlno-store, no-cache, must-revalidate防止敏感 PDF 被缓存
Pragmano-cacheHTTP/1.0 缓存防护
Content-Length<字节数>启用下载进度条

这些默认值遵循 OWASP 安全标头建议。

流式大型 PDF

对于超出可用内存的文件,使用流式模式。这会将 PDF 区块直接写入输出缓冲区,而非在内存中创建整份文件:

php
public function downloadLargeReport()
{
    $pdf = Pdf::create()
        ->setTitle('年度报告');

    foreach ($sections as $section) {
        $pdf->addPage()
            ->setFont('Helvetica', '', 11)
            ->multiCell(0, 6, $section->content);
    }

    return PdfResponse::stream($pdf, 'annual-report.pdf');
}

PdfResponse::stream() 返回一个 StreamedResponse,以区块方式刷新 PDF。无论文件大小,内存用量都维持恒定。

方法签名

php
/** 在浏览器中内嵌显示 PDF。 */
public static function inline(
    PdfDocumentInterface $pdf,
    string $filename,
): Response;

/** 以附件方式强制下载 PDF。 */
public static function download(
    PdfDocumentInterface $pdf,
    string $filename,
): Response;

/** 以流式方式传递 PDF,节省内存。 */
public static function stream(
    PdfDocumentInterface $pdf,
    string $filename,
): StreamedResponse;

响应宏

包注册了两个响应宏,提供便捷用法:

php
// 直接使用 response() 辅助函数
return response()->pdf($pdf, 'report.pdf');           // 下载
return response()->pdfInline($pdf, 'report.pdf');     // 内嵌

这些宏分别委派给 PdfResponse::download()PdfResponse::inline(),所有安全标头皆会应用。

文件名清理

PdfResponse 自动清理文件名参数,防止标头注入攻击。[a-zA-Z0-9._-] 以外的字符会被移除,并强制加上 .pdf 扩展名:

php
// 输入:"../../etc/passwd"
// 清理后:"etcpasswd.pdf"

return PdfResponse::download($pdf, $userInput);

下一步

以 LGPL-3.0-or-later 许可证发布。