文档章节

ajax请求二进制流进行处理(ajax异步下载文件)

张豪飞
 张豪飞
发布于 2017/08/30 10:19
字数 589
阅读 2198
收藏 111
点赞 0
评论 12

需求

  • 管理后台需要随时下载数据报表,数据要实时生成后转换为excel下载。
  • 文件不大,页面放置“导出”按钮,点击按钮后弹出保存文件对话框保存

说明:第一种方法使用a标签直接可以满足大部分人需求,第二种方法纯粹是在说实现方法以及更好的操作体验,不需要(举一个需要第二种方法的例子:如果生成很慢就需要生成过程中禁用按钮,防止连续生成)用到的可以不用看

解决方案

方法一

请求文件的接口能改为GET则可以使用这种方法

<a  class="btn btn-primary btn-xs" download="data.xlsx" href="download/?filename=aaa.txt"><i class="fa fa-share-square-o fa-lg"></i> 导出</a>

或者变换一种方式,使用js动态创建a标签

<button type="button"  onclick="download()">导出</button>
function download() {
    var a = document.createElement('a');
    var url = 'download/?filename=aaa.txt';
    var filename = 'data.xlsx';

    a.href=url;
    a.download = filename;
    a.click()
 }

缺点

  1. 不能使用post方法
  2. 不能在启动下载时禁用按钮、下载完毕启用按钮

方法二

错误方式

常规方法,使用jquery:

<button type="button"  onclick="download()">导出</button>
function download() {
    var url = 'download/?filename=aaa.txt';
    $.get(url, function (data) {
        console.log(typeof(data))
        blob = new Blob([data])
        var a = document.createElement('a');
        a.download = 'data.xlsx';
        a.href=window.URL.createObjectURL(blob)
        a.click()
    })
}

这种方式保存的文件是不能打开的,console.log(typeof(data))会看到是string类型,原因是jquery将返回的数据转换为了string,不支持blob类型。

正确方式

<button type="button"  onclick="download()">导出</button>
function download() {
    var url = 'download/?filename=aaa.txt';
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);        // 也可以使用POST方式,根据接口
    xhr.responseType = "blob";    // 返回类型blob
    // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
    xhr.onload = function () {
        // 请求完成
        if (this.status === 200) {
            // 返回200
            var blob = this.response;
            var reader = new FileReader();
            reader.readAsDataURL(blob);    // 转换为base64,可以直接放入a表情href
            reader.onload = function (e) {
                // 转换完成,创建一个a标签用于下载
                var a = document.createElement('a');
                a.download = 'data.xlsx';
                a.href = e.target.result;
                $("body").append(a);    // 修复firefox中无法触发click
                a.click();
                $(a).remove();
            }
        }
    };
    // 发送ajax请求
    xhr.send()
}

参考资料

受该文章启发 http://www.cnblogs.com/cdemo/p/5225848.html

© 著作权归作者所有

共有 人打赏支持
张豪飞
粉丝 26
博文 35
码字总数 18611
作品 0
郑州
程序员
加载中

评论(12)

你知道啥
你知道啥
这个方法为什么在IE上不能够使用呢?
张豪飞
张豪飞

引用来自“生吃番茄酱”的评论

引用来自“LiShixi”的评论

作者原话:
第二种方法纯粹是在说实现方法以及更好的操作体验,不需要(举一个需要第二种方法的例子:如果生成很慢就需要生成过程中禁用按钮,防止连续生成)用到的可以不用看

如果文件很大,,,浏览器会不会爆炸。。
是的,单纯这样简单是不适合大型文件的
生吃番茄酱
生吃番茄酱

引用来自“LiShixi”的评论

作者原话:
第二种方法纯粹是在说实现方法以及更好的操作体验,不需要(举一个需要第二种方法的例子:如果生成很慢就需要生成过程中禁用按钮,防止连续生成)用到的可以不用看

如果文件很大,,,浏览器会不会爆炸。。
LiShixi
LiShixi
作者原话:
第二种方法纯粹是在说实现方法以及更好的操作体验,不需要(举一个需要第二种方法的例子:如果生成很慢就需要生成过程中禁用按钮,防止连续生成)用到的可以不用看
S_U_D
S_U_D

引用来自“张豪飞”的评论

引用来自“gs586169”的评论

这么麻烦?var a = document.createElement('a');
a.download = 'data.xlsx';
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove(); 这几句代码 我感觉就搞定了, 为什么要先请求流, 然后再保存呢.....
二进制文件,你可以试一下不使用blob保存后是无法打开的。正是因为这些坑才记录的文章

回复@张豪飞 : 呵呵...我系统里面的下载 不管是后台生成的报表, 还是前台的图表下载图片 都用的a标签...难道我做了个假系统不成.....
polly
polly

引用来自“开源中国掌门人”的评论

一个a标签就能搞定的时为啥这么弄:hushed:

@开源中国掌门人 同问,何苦为难自己
张豪飞
张豪飞

引用来自“gs586169”的评论

这么麻烦?var a = document.createElement('a');
a.download = 'data.xlsx';
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove(); 这几句代码 我感觉就搞定了, 为什么要先请求流, 然后再保存呢.....
二进制文件,你可以试一下不使用blob保存后是无法打开的。正是因为这些坑才记录的文章
S_U_D
S_U_D
这么麻烦?var a = document.createElement('a');
a.download = 'data.xlsx';
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove(); 这几句代码 我感觉就搞定了, 为什么要先请求流, 然后再保存呢.....
张豪飞
张豪飞

引用来自“开源中国掌门人”的评论

一个a标签就能搞定的时为啥这么弄:hushed:

引用来自“BBDXF”的评论

我的理解,jQuery的方式更灵活。。。可以加上很多逻辑。
方法二里面说了是错误方式,jquery不支持返回blob,被转换为了字符串,无法转为blob处理
张豪飞
张豪飞

引用来自“开源中国掌门人”的评论

一个a标签就能搞定的时为啥这么弄:hushed:
如果简单get请求就可以那完全不需要的,第一种方法就是。文章主要是说下另一种方法
我的第二个爬虫——爬取今日头条街拍美女

由于界面上的图片都是通过ajax异步请求的,所以我们还是先了解一下ajax的一些基本原理; ajax:Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求。其实说白了就是一个...

hello_我的哥
05/15
0
0
HTML5 FormData+Ajax上传文件表单

文件表单的数据类事multipart/form-data,因此,formData需要特殊处理. 文件上传 参考文章: HTML5 + AJAX ( 原生JavaScript ) 异步多文件上传 [HTML5] Blob对象 通过Ajax方式上传文件,使用...

IamOkay
2017/10/31
0
0
Java中解决(extjs或jquery)session过期退出登录问题

解决两种情况下的用户访问超时: a)普通http请求的session超时; b)异步http请求的session超时,如果使用extjs后大部分的界面刷新都是异步的ajax请求。 不管是那种类型的http请求总是可以由...

Junn
2013/09/24
0
0
Jquery Ajax请求文件下载操作失败的原因分析及解决办法(转载)

jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯。 一、失败的原因 那是因为response原因,一般请求浏览器是会处理服务...

卯金刀GG
2016/09/28
28
0
jxl 、 apache.poi.hssf 实现本地, 服务器断的下载

上面的两个都是将数据库中的数据组装成excel 的格式,并进行下载,怎么让他下载,或者说用何种方式来请求下载资源,方式有如下两种。 1、使用ajax异步请求将数据使用 response 的OutputStrea...

QH_C
2015/03/01
0
0
对 Ajax 的一次复盘

Ajax = 即为异步的 JavaScript 和 XML,它并不是新的编程语言,而是一种使用现有标准的新方法,最大的优点在于不需要重新更新整个页面的情况下,可以与服务器交换数据并更新部分的网页内容。...

果汁凉茶丶
2017/12/29
0
0
[Ajax-相濡以沫,不如相忘于江湖] Ajax初识

Ajax的全称是 Asynchronous JavaScript And XML,即异步JavaScript和XML。2005年由Jesse James Garrett首先提出。在之后极短的时间内,Ajax被广泛应用到大量B/S结构的应用中,改进了传统的W...

LSantorini
2016/01/26
30
0
从零开始学 Web 之 Ajax(三)Ajax 概述,快速上手

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN...

Daotin
07/17
0
0
JQuery——实现Ajax应用

实现Ajax应用 1 .load()异步请求数据,通过Ajax请求加载服务器中的数据,并把返回的数据放置到指定的元素中,调用格式为load(url,[data],[callback]) 2 参数url为加载服务器地址,可选项dat...

拉考的考拉
2017/11/23
0
0
JavaScript本来就很简单(神说ajax)

js中的ajax ajax:异步的JavaScript和XML,首先它是一门用于前后台数据交互的技术,这里有两个比较有趣的概念(同步与异步)说白了就是后台传回来的数据,同步的话,你必须刷新页面才能更新数...

云焱
2017/09/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
9
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
4
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
176
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部