Laravel8结合PhpWord/Ajax下载Word自定义文件名及直链报错求助
Ajax下载固定文件名问题解决方案
后端控制器修改
你需要在返回下载响应时指定文件名,同时配置正确的MIME类型:
public function download($id, $downloadName = null) { $data2 = array(); $data_modele = Model_Contrat::where('id_modele_contrat',$id)->firstOrFail(); $filename= $data_modele->fichier; // 不要硬编码绝对路径,用Laravel内置辅助函数适配不同环境 $filepath = storage_path('app/public/uploads/modeles_contrat/'.$filename); if (file_exists($filepath)) { $headers = [ // docx文件的正确MIME类型 'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', ]; $downloadName = $downloadName??$filename; // 第二个参数传入下载文件名,Laravel会自动生成Content-Disposition响应头 return response()->download($filepath, rawurlencode($downloadName), $headers); } else { $data2['success'] = 2; $data2['message'] = 'File not uploaded.'; return response()->json($data2, 404); } }
前端JS修改
从响应头中获取后端返回的文件名,替换固定的casting.docx:
$(document).on('click', '.download', function(){ var id = $(this).attr('id'); $.ajax({ url:"modeles_contrat/"+id+"/download", type:"GET", xhrFields: { responseType: 'blob' }, // 新增xhr参数获取响应头 success: function(response, status, xhr) { var blob = new Blob([response]); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); // 从响应头提取文件名 const disposition = xhr.getResponseHeader('Content-Disposition'); const fileName = decodeURIComponent(disposition.match(/filename="?([^"]+)"?/)[1]); link.download = fileName; link.click(); // 释放blob资源避免内存泄漏 window.URL.revokeObjectURL(link.href); }, error: function() { $('#responseMsg').removeClass("alert-success"); $('#responseMsg').addClass("alert-danger"); $('#responseMsg').html('请生成合同'); $('#responseMsg').show(); } }) });
普通链接下载跳转异常解决方案
你当前的代码存在多个语法和逻辑错误,逐一修复即可:
1. 修复a标签拼接错误
原代码href属性的引号拼接错误,导致生成的URL不合法:
// 修复前错误代码 // $button .='<a href="/modeles_contrat/"'.$data->id_modele_contrat.'"/download" class="btn btn-xs btn-info pull-right" data_id="'.$data->id_modele_contrat.'" >下载</a>'; // 修复后代码 $button .='<a href="/modeles_contrat/'.$data->id_modele_contrat.'/download" class="btn btn-xs btn-info pull-right" data_id="'.$data->id_modele_contrat.'" >下载</a>';
2. 修复控制器代码
public function download($id_modele_contrat) { // 用findOrFail避免id不存在时调用属性报错 $data_modele = Model_Contrat::where('id_modele_contrat',$id_modele_contrat)->firstOrFail(); $filename = $data_modele->fichier; // 替换硬编码路径为Laravel内置辅助函数生成的路径 $filepath = storage_path('app/public/uploads/modeles_contrat/'.$filename); if (file_exists($filepath)) { $headers = [ 'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', ]; return response()->download($filepath, $filename, $headers); } // 补全文件不存在的返回逻辑 abort(404, '文件不存在'); }
额外注意事项
- 确保
storage/app/public/uploads/modeles_contrat目录有可读权限 - 如果你已经执行了
php artisan storage:link,也可以用public_path()生成对应公共路径的地址
内容的提问来源于stack exchange,提问作者saadia
相关产品推荐
相关产品推荐

