Laravel 9中通过Axios生成下载CSV文件的乱码问题排查
解决Laravel 9 + Axios生成CSV乱码及无法打开问题
后端代码修正
核心问题点
- 数组处理错误:
array_merge($header, $lines)会把一维表头和二维数据行合并成一维数组,导致fputcsv仅写入一行错误数据,这是文件内容异常的关键原因。 - 响应头配置错误:
Content-Encoding: UTF-8属于误用,该字段用于指定压缩编码(如gzip),而非字符编码;需在Content-Type中明确声明字符集。 - 缺少UTF-8 BOM:Excel、记事本等软件需要BOM标识才能正确识别UTF-8编码的CSV文件。
修正后代码
// $header为一维表头数组,$lines为二维数据行数组,无需合并 $headers = array( "Content-type" => "text/csv; charset=utf-8", "Content-Disposition" => "attachment; filename=file.csv", "Pragma" => "no-cache", "Cache-Control" => "must-revalidate, post-check=0, pre-check=0", "Expires" => "0" ); $callback = function() use($header, $lines) { $file = fopen('php://output', 'w'); // 写入UTF-8 BOM,确保办公软件识别编码 fputs($file, chr(0xEF) . chr(0xBB) . chr(0xBF)); // 写入表头行 fputcsv($file, $header); // 循环写入每一条数据 foreach ($lines as $line) { fputcsv($file, $line); } fclose($file); }; return response()->stream($callback, 200, $headers);
前端代码修正
核心问题点
Axios默认响应类型为json,会自动解析响应内容,导致CSV二进制数据被错误转码,最终生成乱码文件。需指定响应类型为blob,直接获取原始二进制数据。
修正后代码
axios.post('{{ route("shiple.table") }}', filters, { // 关键配置:指定响应类型为blob responseType: 'blob' }) .then(function (response) { const url = window.URL.createObjectURL(response.data); const link = document.createElement('a'); link.href = url; link.setAttribute('download', 'file.csv'); document.body.appendChild(link); link.click(); // 释放URL对象,避免内存泄漏 window.URL.revokeObjectURL(url); document.body.removeChild(link); }) .catch(function (error) { console.log(error); });
内容的提问来源于stack exchange,提问作者Phyron
相关产品推荐
相关产品推荐

