Laravel使用response download无法下载文件,出现404错误
Laravel 文件下载404错误排查与修复
问题场景
使用Laravel的response()->download()实现文件下载时触发404页面未找到错误,已为storage目录创建symlink,文件存储在可通过public目录访问的路径下。
Blade视图代码
<div class="mb-3"> <label for="lampiran" class="form-label">Lampiran</label> <div class="input-group mb-3"> <input type="text" class="form-control @error('lampiran') is-invalid @enderror" value="{{ $dokumentasi->lampiran }}" readonly> {{-- <span class="input-group-text"><a href="{{ route('history.download', Crypt::encrypt($dokumentasi->id)) }}"><i class="fa fa-download" aria-hidden="true"></i></a></span> --}} <span class="input-group-text"><a href="{{ route('history.download', ($dokumentasi->lampiran)) }}"><i class="fa fa-download" aria-hidden="true"></i></a></span> </div> </div>
控制器代码
public function download($file_name) { $file_path = base_path($file_name); return response()->download($file_path); }
路由配置(web.php)
Route::get('/lampiran-nde/{file}', 'download')->name('history.download');
错误原因及修复方案
1. 路由未指定控制器类
Laravel路由无法仅通过方法名'download'定位到对应控制器,必须明确控制器类名:
// Laravel 8+ 语法 Route::get('/lampiran-nde/{file}', [HistoryController::class, 'download'])->name('history.download'); // Laravel 8以下版本语法 Route::get('/lampiran-nde/{file}', 'HistoryController@download')->name('history.download');
2. 文件路径拼接错误
base_path()指向项目根目录,若文件存储在storage/app/public(已通过symlink映射到public/storage),需调整路径获取方式:
public function download($file_name) { // 方案1:直接读取storage内的源文件(推荐) $file_path = storage_path('app/public/' . $file_name); // 先校验文件存在性,避免触发服务器错误 if (!file_exists($file_path)) { abort(404); } return response()->download($file_path); } // 方案2:通过public目录的symlink读取 public function download($file_name) { $file_path = public_path('storage/' . $file_name); if (!file_exists($file_path)) { abort(404); } return response()->download($file_path); }
3. URL参数含特殊字符导致路由匹配失败
若$dokumentasi->lampiran包含斜杠、空格等特殊字符,会破坏路由规则,需做编码处理:
- Blade视图中对参数编码:
<a href="{{ route('history.download', urlencode($dokumentasi->lampiran)) }}">
- 路由允许匹配带斜杠的参数:
Route::get('/lampiran-nde/{file}', [HistoryController::class, 'download']) ->where('file', '.*') ->name('history.download');
4. 文件权限问题
确保storage目录及文件有服务器读写权限,执行以下命令:
chmod -R 755 storage/ chown -R www-data:www-data storage/ # 根据服务器运行用户调整
内容的提问来源于stack exchange,提问作者ProgrammerWannabe
相关产品推荐
相关产品推荐

