Laravel中JS处理API返回的PDF二进制字符串下载异常问题
问题:JavaScript转换API返回的PDF二进制字符串为可下载文件时损坏
我在Laravel项目中调用一个需Bearer认证的API获取PDF二进制字符串,示例内容如下:
%PDF-1.7 %���� 6 0 obj <<Length 5 0 R/Filter/FlateDecode/N 3/Range[0 1 0 1 0 1 ]>> stream x���wTS��Ͻ7�P����khRH �H�.*1 J�� etc...
需要在JavaScript中将其转换为可下载文件,尝试了以下代码:
function downloadVisura(){ axios.get('https://catasto.openapi.it/visura_catastale/' + "{{$visura->id_visura}}" + '/documento', { headers: { 'accept': 'application/pdf', 'Authorization': 'Bearer [Token_Censored]' } }) .then ( (res) => { data = res.data; console.log(data); var blob = new Blob([data], {type: 'application/pdf'}); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = "visura.pdf"; link.click(); }) }
但通过该方式下载的130KB文件损坏,而使用curl --output下载的76KB文件可正常打开。
解决方案
问题核心在于axios默认会将响应解析为UTF-8字符串,PDF作为二进制文件,转码过程会破坏原始数据,导致文件损坏、体积变大。只需在axios请求中添加responseType配置,指定接收二进制数据即可。
方法1:直接获取Blob对象
修改请求配置,添加responseType: 'blob',直接使用返回的Blob生成下载链接:
function downloadVisura(){ axios.get('https://catasto.openapi.it/visura_catastale/' + "{{$visura->id_visura}}" + '/documento', { headers: { 'accept': 'application/pdf', 'Authorization': 'Bearer [Token_Censored]' }, responseType: 'blob' // 关键配置:指定接收Blob类型 }) .then ( (res) => { const blob = res.data; const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = "visura.pdf"; link.click(); // 释放URL对象,避免内存泄漏 window.URL.revokeObjectURL(link.href); }) .catch(err => { console.error('下载失败:', err); }); }
方法2:使用ArrayBuffer转换为Blob
也可以指定responseType: 'arraybuffer',再将ArrayBuffer转换为Blob:
function downloadVisura(){ axios.get('https://catasto.openapi.it/visura_catastale/' + "{{$visura->id_visura}}" + '/documento', { headers: { 'accept': 'application/pdf', 'Authorization': 'Bearer [Token_Censored]' }, responseType: 'arraybuffer' // 指定接收ArrayBuffer }) .then ( (res) => { const blob = new Blob([res.data], {type: 'application/pdf'}); const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = "visura.pdf"; link.click(); window.URL.revokeObjectURL(link.href); }) .catch(err => { console.error('下载失败:', err); }); }
两种方法都能保证原始二进制数据的完整性,生成的PDF文件可正常打开,体积也会和curl下载的一致。
内容的提问来源于stack exchange,提问作者Federico Pavone
相关产品推荐
相关产品推荐

