You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:53:13