前端请求解析文件流并下载文件

本文介绍了使用axios下载文件流的两种方法,包括Blob对象和FileReader实例,并讨论了如何处理后端动态文件名。重点在于API操作和文件名解码技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种方法接收下载文件流

                this.$axios({
                    url: `/md2api/attachment/c/${val.code}`,
                    method: "GET",
                    responseType: 'blob',   //设置响应格式
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                    },
                })
                .then(function (response) {
                    let b = new Blob([response.data]);     //拿到文件流下载对象
                    let url = window.URL.createObjectURL(b);  //生成文件流下载链接
                    let a = document.createElement('a');      //创建一个a标签用来跳转
                    a.href = url;                             // a标签 href  赋值 链接  
                    a.download = 'ing.jpeg';                  //设置下载文件的文件名和文件格式
                    document.body.appendChild(a);             //将标签DOM,放置页面
                    a.click();                              
                    window.URL.revokeObjectURL(url);     //释放 url 对象内存
                    document.body.removeChild(a);        //移除标签节点
                })
                .catch(function (error) {
                    console.log(error);
                });

第二种方法接收下载文件流(采用 FileReader 实例对象调用Api ,处理文件流)推荐使用

                this.$axios({
                    url: `/md2api/attachment/c/${val.code}`,
                    method: "GET",
                    responseType: 'blob',   //设置响应格式
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                    },
                })
                .then(function (response) {
                    const reader = new FileReader();   //  实例化 FileReader
                    reader.readAsDataURL(response.data); //将读取到的文件编码成DataURL
                    reader.onload = (e) => {      //调用API onload  文件读取成功时触发   
                        //模拟a标签点击
                        let a = document.createElement('a');   //创建a标签,
                        a.download = Date.parse(new Date()) + '.jpeg';   //设置格式
                        a.href = e.target.result;               //下载文件流链接
                        document.body.appendChild(a);           //将标签DOM,放置页面
                        a.click();
                        document.body.removeChild(a);          //移除标签节点
                    };
                     reader.onerror = (e) => {
                       this.$message({
                           message: '解析文件发生错误',
                           type: 'warning'
                        });
                     };
                     reader.onabort= (e) => {
                      this.$message({
                          message: '解析文件发生意外终止',
                          type: 'warning'
                       });
                    }
                 })
                .catch(function (error) {
                    console.log(error);
                });

从流文件中动态解析文件名

  • 如果后端在流文件中,返回的有动态文件名,则可直接拿来用,如果没有就需要,手动去解析获取流文件名。如果后端返回的流文件名使用的是经过encodeURIComponent字符串名进行编码后的效果,则可以使用 decodeURIComponent 将其解码回原始字符。下面是一个示例:
const encodedString = encodeURIComponent(" Hello World!");  //'Hello%20World%21'
const decodedString = decodeURIComponent(encodedString);

console.log(decodedString); // 输出: Hello World!  拿取到原文件名

扩展
FileReader 对象 常用 API 回调函数

API描述
onload 文件读取成功时触发
onerror 解析文件发生错误时触发
onabort解析文件发生意外终止时触发
onloadend文件读取完毕之后,成功或者失败都会触发
onloadstart开始读取时触发
onprogress读取时触发

FileReader 常用的 API 数据处理钩子函数

API描述
readAsText()读取文本文件
readAsBinaryString()读取任意类型的文件,返回二进制字符串
readAsDataURL()将读取到的文件编码成 DataURL
abort()终止读取

🚵‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼‍♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————

<think>好的,用户想要在前端实现接收文件流下载PDF的功能,需要找到最佳实践和代码示例。首先,我得回忆一下前端处理文件下载的常见方法。根据引用[1],前端下载文件有多种方式,比如使用a标签的download属性、Blob对象和FileSaver库,或者动态生成文件内容。用户提到的是文件流,所以应该考虑如何处理二进制流数据。 接下来,用户的需求是接收文件流下载PDF。通常,后端会返回文件流前端需要将其转换为可下载文件。引用[3]提到了使用Blob来处理二进制数据,适合下载,所以可能要用到Blob对象。同时,引用[3]还提到html2canvas可以将DOM生成图片,但这里的情况是处理PDF文件流,所以可能需要不同的方法。 首先,前端如何接收文件流?通常通过AJAX请求,比如fetch或XMLHttpRequest,设置正确的响应类型。例如,设置responseType为'blob',这样返回的数据可以直接作为Blob对象处理。然后,创建URL.createObjectURL(blob)生成临时链接,再通过a标签触发下载。 需要注意浏览器兼容性。引用[1]提到不同浏览器对download属性的支持不同,但现代浏览器基本都支持。对于旧版浏览器,可能需要使用其他方法,比如在新窗口打开链接,但这样可能无法控制文件名。 代码示例方面,使用fetch获取文件流,设置responseType为'blob',然后处理返回的Blob。使用URL.createObjectURL创建链接,动态创建a标签,设置download属性为文件名,触发点击事件。下载完成后,要记得释放URL对象,避免内存泄漏。 另外,是否需要设置请求头?比如如果后端需要认证,可能需要携带token或其他认证信息,这需要根据具体情况添加。 可能的问题:如果后端返回的是JSON而不是Blob,如何处理?需要确保响应头中的Content-Type正确,比如application/pdf,或者前端正确解析响应。此外,文件名可能需要从Content-Disposition头中提取,这部分处理可能需要额外的代码,比如解析响应头中的filename参数。 总结步骤:1. 发送请求获取文件流,正确设置responseType。2. 将响应转换为Blob。3. 创建对象URL。4. 创建a标签触发下载。5. 清理临时URL。 现在要检查是否有最佳实践的注意事项,比如错误处理、兼容性处理、内存释放等。例如,使用try-catch处理可能的错误,确保在下载后调用URL.revokeObjectURL。此外,对于大文件,可能需要显示下载进度,但用户的问题没有提到,所以可能不需要。 最后,根据引用[2],处理半结构化数据如PDF可能需要特定库,但这里用户的需求只是下载,不需要解析内容,所以不需要用到LangChain之类的工具。因此,答案应集中在如何处理文件流触发下载。</think>### 前端通过文件流下载PDF的最佳实践及代码示例 #### 实现步骤说明 1. **接收文件流**:通过`fetch`或`XMLHttpRequest`请求后端接口,设置`responseType: 'blob'`明确接收二进制数据流[^1][^3]。 2. **转换为Blob对象**:将响应数据包装为`Blob`类型,指定MIME类型为`application/pdf`。 3. **生成临时URL**:使用`URL.createObjectURL(blob)`生成可下载的临时链接。 4. **触发文件下载**:动态创建`<a>`标签,设置`download`属性定义文件名,模拟点击事件完成下载。 5. **资源释放**:下载完成后通过`URL.revokeObjectURL()`释放内存。 #### 代码示例 ```javascript // 使用fetch API实现 async function downloadPDF() { try { const response = await fetch('/api/download-pdf', { method: 'GET', headers: { 'Authorization': 'Bearer your_token' // 需要认证时添加 }, responseType: 'blob' // 关键参数声明接收二进制流 }); if (!response.ok) throw new Error('文件下载失败'); const blob = await response.blob(); const downloadUrl = URL.createObjectURL(blob); // 创建隐藏的下载链接 const link = document.createElement('a'); link.href = downloadUrl; link.download = 'document.pdf'; // 可通过Content-Disposition解析文件名 document.body.appendChild(link); link.click(); // 清理资源 document.body.removeChild(link); URL.revokeObjectURL(downloadUrl); } catch (error) { console.error('下载失败:', error); } } // 调用下载函数 downloadPDF(); ``` #### 关键优化点 1. **文件名处理**:建议后端在响应头中添加`Content-Disposition: attachment; filename="file.pdf"`,前端可通过解析响应头获取更精确的文件名。 2. **大文件处理**:添加进度指示器(通过`response.body.getReader()`实现流式读取)。 3. **错误处理**:捕获网络错误(如HTTP状态码非200)和数据处理异常。 4. **兼容性保障**:对不支持`download`属性的浏览器(如IE)采用`window.open(url)`的降级方案。 #### 应用场景 - 动态生成的PDF报表下载 - 保密文档的授权下载(结合身份验证) - 大数据量导出场景(避免浏览器内存溢出)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旧梦星轨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值