前面一直做过下载的功能。就是后台将文件流写入response里面,然后就好了。前台会自动弹出下载提示等。

今天打算做一个ajax下载。想当然的结果死活浏览器没反应。我擦。

然后浏览器调试,发现response返回过来的是一串类似乱码的文本而不是二进制文件流。定位原因在这里。

之后继续百度,如何实现ajax异步下载。回答是这样的:

  那就是请求方式有问题,文件下载的请求是不能写在ajax里面的!

  原因:因为response原因,一般请求浏览器是会处理服务器输出的response,例如生成png、文件下载等,然而ajax请求只是个“字符型”的请求,即请求的内容是以文本类型存放的。文件的下载是以二进制形式进行的,虽然可以读取到返回的response,但只是读取而已,是无法执行的,说白点就是js无法调用到浏览器的下载处理机制和程序。

然后继续百度,我有点不信邪。找到这篇文章:http://www.cnblogs.com/cdemo/p/5225848.html

原来ajax并非只能获取文本而不能获取二进制流,只是jquery封装的ajax的问题。

  

抱怨:jquery做了这么久了 一个ajax方法还停留在几年前的xmlhttprequest 1的版本中,惊人的不支持流文件!!!

我这还怎么大肆推行我的前后台完全隔离思想~~。算了不抱怨了,果然是不能靠别人,只能自己写了。

楼主依稀记得 xmlhttprequest 2 标准中支持流文件的,并且应该使用 xhr.response作为返回 而不是responseText。

于是使用原生的ajax获取流文件:

  

var url = serverUrlBase + "/server/images/" + mapid + "/files/png";
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.setRequestHeader("client_type", "DESKTOP_WEB");
xhr.setRequestHeader("desktop_web_access_key", _desktop_web_access_key);
xhr.onload = function() {
if (this.status == 200) { }
}
xhr.send();

获取到了文件,然后原贴中需要的操作是展示,使用blob对象。

  这样应该可行,但是怎么处理请求的数据呢? ???? 这个问题。 对了 html5新特性里面是不是 提到一个 Blob对象来着。试试看。

  通过查阅相关blob资料,查阅  4.6.9 The response attribute 得知 返回类型应该使用

于是原贴中剩下的是建造img标签,赋值各个属性,结果得到了。

然后我懵逼了,我需要的是下载啊。有点急着要结果,所以我先放开了这种思路。

我记得搜索得到别人的做法是使用一个iframe,得到不刷新原来页面下载的效果,也就是它使用直接其它层直接访问的方式模拟了ajax。发现,真简单:

参考这篇文章:http://www.jb51.net/article/47294.htm

代码:

  

<script>
function download()
{
//下载文件的地址
var url="http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/13618994/13618995183600128.mp3?xcode=48d4a720fcd9a974586066d0145f7207";
document.getElementById("ifile").src=url;
}
</script>
<a href="#" onclick="download()">download</a>
<iframe id="ifile" style="display:none"></iframe>

区别只是将我的链接替换进去了。

效果达到了,但还有点不死心,轻易得到的东西总是不会珍惜。我还是想看看我的ajax下载。我想啊,我都能在页面得到元素了,为什么我不能下载呢?

于是百度搜索前端js下载

刚好发现了一篇文章:http://blog.csdn.net/greatbody/article/details/70207232

思路:

我已经做好了一半了。剩下下载就是了。于是我模拟它的方法将自己的代码改写了一下。

<script type="text/javascript">
function f() {
var url = "/servlet/example";
// document.getElementById("ifile").src=url;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.onload = function() {
if (this.status == 200) {
var blob = this.response;
downloadFile(fileNameFromHeader(xhr.getResponseHeader("Content-Disposition")), xhr.response);
}
}
xhr.send();
} function fileNameFromHeader(disposition) {
var result = null;
if (disposition && /filename=.*/ig.test(disposition)) {
result = disposition.match(/filename=.*/ig);
return decodeURI(result[0].split("=")[1]);
}
return "undefine_file";
}
function downloadFile(fileName, content) {
var aLink = document.createElement('a');
var blob = new Blob([content]);
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
if (fileName) {
aLink.download = fileName;
}
aLink.target = "_blank";
aLink.href = URL.createObjectURL(blob);
aLink.dispatchEvent(evt);
}
</script>

注意它前端下载的代码:

function downloadFile(fileName, content) {
var aLink = document.createElement('a');
var blob = new Blob([content]);
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
if (fileName) {
aLink.download = fileName;
}
aLink.target = "_blank";
aLink.href = URL.createObjectURL(blob);
aLink.dispatchEvent(evt);
}

创建一个a连接,a链接的地址为要访问的对象,这里是我们的Blon对象,然后js点击,在新窗口。

 

  

ajax下载,前端js下载(转)的更多相关文章

  1. OSS阿里云上传文件 前端js下载url跨域问题

    场景: 1.后端上传文件至阿里云OSS,返回得到一个URL. 2.前端用这个URL下载文件,ajax请求异常:No 'Access-Control-Allow-Origin' header is pr ...

  2. Web前端js下载流文件

    前端下载文件大概有以下种: 1)a标签链接下载 <a href="url">点击链接下载</a> 2)表单form提交下载 var form = $(&qu ...

  3. 前端JS 下载大文件解决方案

    问题场景 点击导出按钮,提交请求,下载excel大文件(超过500M),该文件没有预生成在后端, 直接以文件流的形式返回给前端. 解决方案 在Vue项目中常用的方式是通过axios配置请求,读取后端返 ...

  4. 前端JS下载文件总结

    Data URLs Data URLs: 即前缀为data: 协议的URL,其允许内容创建者向文档中嵌入小文件. 例如:可以直接在HTML中的img元素直接使用Data URLs : data:[&l ...

  5. 小谢第10问:前端JS下载文件、表格

    对于小型文件及表格下载,一般采用a标签形式 <buttonb @click="downloadTemplate()">模板下载</button> downl ...

  6. 前端js保存页面为图片下载到本地

    前端js保存页面为图片下载到本地 手机端点击下载按钮将页面保存成图片到本地 前端js保存页面为图片下载到本地的坑 html2canvas 识别 svg 解决方案 方案 html2canvas.js:可 ...

  7. 10.用js下载文件(需要后端链接)

          用js下载文件 PS:本文说的,并非如何用js创建流.创建文件.实现下载功能. 而是说的:你已知一个下载文件的后端接口,前端如何请求该接口,实现点击按钮.下载文件到本地.(可以是zip啦. ...

  8. .net WebApi 批量文件进行压缩zip以二进制流传输至前端(Vue)下载

    前言:最近接了个项目,需要进行将服务端生成的文件进行打包压缩供前端下载,百度查了下资料,决定采用SharpZipLib C#开园的压缩解压库进行服务器文件压缩,在实现过程,郁闷的是前端接收下载下来的压 ...

  9. node.js 下载安装及gitbook环境安装、搭建

    最近需要gitbook看文档,于是各种百度,各种安装,很多都是无法正常安装完成的,比较纠结啊 最后,终于发现一个好用的,现分享一下地址(也是给自己做个记录): 1.node.js下载地址: http: ...

随机推荐

  1. 【Python学习 】Python实现的FTP上传和下载功能

    一.背景 最近公司的一些自动化操作需要使用Python来实现FTP的上传和下载功能.因此参考网上的例子,撸了一段代码来实现了该功能,下面做个记录. 二.ftplib介绍 Python中默认安装的ftp ...

  2. 第1章 1.9计算机网络概述--OSI参考模型和网络安全

    1.物理层安全: 风险:无关人员接入网络. 防范:将用不到的口的网线拔掉,或者用命令将用不到的网线接口shutdown(关闭). 2.数据链路层安全: ADSL账号密码 无线网账号密码 交换机绑定MA ...

  3. python 面向对象 字典 有序字典

    和原来字典一模一样 把dict 传进去 相当于这个类就是一个字典 # 把dict 传进去 相当于这个类就是一个字典 class Mydict(dict): pass d = Mydict() prin ...

  4. SSL/TSL握手过程详解

    1. Client Hello 握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1.客户端支持的加密套件(Support Ciphe ...

  5. layer官方演示与讲解(jQuery弹出层插件)

    1. 使用layer遇到困难?Fly社区虔诚为您解惑 2. layer 2.0 发布,以独立形式呈现的最后一个版本 3. Fork layer on Github,爱她,就给她加个星啵 当前版本:2. ...

  6. 自定义centos7 yum仓库

    将安装光盘插入 mkdir /newyum umount /dev/sr0 mount /dev/sr0 /media cp -rf /media/Packages /newyum #将镜像中的rpm ...

  7. 2018 Multi-University Training Contest 5 Solution

    A - Always Online Unsolved. B - Beautiful Now Solved. 题意: 给出一个n, k  每次可以将n这个数字上的某两位交换,最多交换k次,求交换后的最大 ...

  8. uva11324 有向图的强连通分量+记忆化dp

    给一张有向图G, 求一个结点数最大的结点集,使得该结点集中任意两个结点u和v满足,要么u可以到达v, 要么v可以到达u(u和v相互可达也可以). 因为整张图可能存在环路,所以不好使用dp直接做,先采用 ...

  9. centos6 pip install python-ldap报错

    error: Setup script exited with error: command 'gcc' failed with exit status 1 解决方法: 原因是版本不兼容,centos ...

  10. bzoj1619 / P2919 [USACO08NOV]守护农场Guarding the Farm

    P2919 [USACO08NOV]守护农场Guarding the Farm 相似题:P3456 [POI2007]GRZ-Ridges and Valleys 按海拔是否相同分块 每次bfs海拔相 ...