
Laravel 文件下载核心是 response()->download() 方法返回带正确 HTTP 头的响应。基础下载需确保本地文件存在且可读,推荐用 storage_path() 或 public_path() 构建绝对路径;动态生成下载用 streamDownload() 配合闭包输出内容;安全下载须校验权限并从 private 目录读取后流式响应;注意中文文件名编码、大文件内存限制及 Web 服务器配置。
在 Laravel 中处理文件下载请求,核心是使用 response()->download() 方法返回一个带有正确 HTTP 头的响应,触发浏览器下载行为。
最常见场景是提供项目中已存在的文件(如 storage/app 或 public 目录下的文件)供用户下载。
Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException
storage_path() 或 public_path() 构建绝对路径return response()->download(storage_path('app/reports/2025-summary.pdf'), '年度报告.pdf');
不保存到磁盘,而是生成内容后直接流式响应。适合导出报表、生成临时凭证等场景。
response()->streamDownload() 接收一个闭包,闭包内输出原始内容(如用 fputcsv 写 CSV,或用 Dompdf/TCPDF 渲染 PDF)Content-Type
和 Content-Disposition 头$data = [['姓名', '邮箱'], ['张三', 'zhang@example.com']];
return response()->streamDownload(function () use ($data) {
$fp = fopen('php://output', 'w');
foreach ($data as $row) {
fputcsv($fp, $row);
}
fclose($fp);
}, 'users.csv', [
'Content-Type' => 'text/csv',
]);
不能直接暴露 storage 或 public 路径给前端,应通过路由+控制器做访问控制。
storage/app/private/ 等非公开目录Storage::disk('local')->get($path) 读取内容,再用 response()->stream() 返回if (! $user->can('view', $document)) {
abort(403);
}
$content = Storage::disk('local')->get("private/documents/{$document->id}.pdf");
return response($content)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'attachment; filename="'.$document->title.'.pdf"');
避免踩坑的关键点:
download() 会自动处理;旧版本可用 rawurlencode() 手动编码download()(会一次性加载进内存),优先考虑 StreamedResponse 或 Nginx/Apache 的 X-Sendfile/X-Accel-Redirect/storage 路由,否则 public/storage 符号链接方式可能失效responseType: 'blob',否则响应体可能被 JSON 解析器误处理基本上就这些。用对方法,下载逻辑既安全又轻量。