Laravel Storage无法强制下载备份文件问题求助
备份文件下载乱码问题解决方法
问题场景
在Vue.js表格展示备份文件列表,点击下载按钮通过axios请求Laravel后端接口时,返回以PK开头的乱码内容,无法正常触发文件下载。
相关代码
Vue代码
<tr v-show="backups.length" v-for="backup in backups" :key="backup.id"> <td>{{backup.path}}</td> <td>{{backup.size}} KB</td> <td> <v-button type="sm-secondary" title="Download" @click="downloadBackup(backup.path)"> <i class="fa-solid fa-download"></i> </v-button> </td> </tr> <script> export default { methods: { downloadBackup(path) { axios.get('/download-backup-system/'+path) .then(response => { console.log(response) }) .catch(error => { console.log(error) }) } } } </script>
注:后端返回的文件路径示例:
C:\...\storage\app/Backup/2022-11-28-10-21-27.zip
Laravel控制器代码
public function downloadBackups($path) { $Filepath = storage_path('app/Backup/'.$path); if (file_exists($Filepath)) { return Response::download($Filepath); } }
问题原因
axios默认将响应内容当作文本解析,而zip文件是二进制格式,直接解析会出现乱码(PK是zip文件的文件头标识)。
解决方法
修改axios请求配置,指定响应类型为blob,并在拿到响应后手动创建下载链接触发浏览器下载:
修改后的Vue方法代码
downloadBackup(path) { axios.get('/download-backup-system/'+path, { responseType: 'blob' // 指定响应为二进制blob类型 }) .then(response => { // 创建blob对象 const blob = new Blob([response.data], { type: response.headers['content-type'] }); // 创建临时下载链接 const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; // 从响应头提取文件名,默认backup.zip const contentDisposition = response.headers['content-disposition']; let filename = 'backup.zip'; if (contentDisposition) { const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); if (matches != null && matches[1]) { filename = decodeURIComponent(matches[1].replace(/['"]/g, '')); } } a.download = filename; // 触发下载动作 document.body.appendChild(a); a.click(); // 清理临时资源 window.URL.revokeObjectURL(url); document.body.removeChild(a); }) .catch(error => { console.log(error); }) }
补充说明
Laravel的Response::download()方法已经自动设置了正确的响应头(包括Content-Type和Content-Disposition),无需修改后端代码,确保文件路径正确即可。
内容的提问来源于stack exchange,提问作者Maison012
相关产品推荐
相关产品推荐

