ajax下载,前端js下载(转)

前面一直做过下载的功能。就是后台将文件流写入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点击,在新窗口。

 

  

时间: 2024-10-08 11:35:03

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

js 下载文件 修改文件名

用js下载文件,使用<a>标签,添加download属性即可. var a = document.createElement("a"); a.href = "http://XXX.com/audioStream/8a9dbae9d0859e48fc1f590fcf6d4ccc.mp3": a.download ="test.mp3"; a.click(); 但是如果想给文件重新命名,貌似js无法实现. 因此考虑后台实现,用java代理

js下载文件,判断文件是否返回

下载之前用的window.location.href下载的,但是这个判别不了文件是否返回,小文件倒还好,大的文件长时间没有下载也没有加载条什么的,用户有时会点击下载好几下,大的数据很容易将服务拖垮,所以决定改良下,参考网上大神的,大概思路是:用ifram标签下载,追加到文档,下载完成移除,前端带一个时间戳的cookie,后台接收,下载完成之后返回,前端一个定时循环的函数去验证是不是返回了时间戳,如果是确认下载成功 前端代码: $("#mylink").click(function ()

Node.js下载安装图文教程

一.Node.js是什么? Node.js是前端js代码的一个包管理工具,类似于javar的Maven或.net的Nuget 二.Node.js的下载与安装 1.官网下载地址:https://nodejs.org/zh-cn/ 2.双击打开,开始安装 三.Node.js的验证 node -v npm -v 四.npm镜像仓库源配置(用国内的源可以提高下载速度) npm config set registry http://registry.npm.taobao.org/ 原文地址:https:/

两种 js下载文件的方法(转)

function DownURL(strRemoteURL, strLocalURL){ try{ var xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP"); xmlHTTP.open("Get", strRemoteURL, false); xmlHTTP.send(); var adodbStream = new ActiveXObject("ADODB.Stream"); adodbStrea

Js下载文件到本地(兼容多浏览器)

在客户端通过js下载文件,试过几种下载方式,iframe方式仅限于IE浏览器,window.open(url),location.href=url 这两种方式在chrome浏览器还会是直接打开文件而不是下载,百度N久没有结果,在谷歌还是找到答案了,下载链接在此. window.downloadFile = function (sUrl) { //iOS devices do not support downloading. We have to inform user about this. i

Node.js下载及安装

Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快.易于扩展的网络应用. Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行的数据密集型的实时应用. V8引擎执行Javascript的速度非常快,性能非常好.Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好. Node是一个Javascript运行环境(runtime).实际上它是对Google V8引擎进行了封

Node.js abaike图片批量下载Node.js爬虫1.00版

这个与前作的差别在于地址的不规律性,需要找到下一页的地址再爬过去找. //====================================================== // abaike图片批量下载Node.js爬虫1.00 // 2017年11月9日 //====================================================== // 内置http模块 var http=require("http"); // 内置文件处理模块,用于创

去掉网上拽下来的js&#39;.下载&#39;后缀 | 随便搞

import os if __name__ == '__main__': # 文件路径 dir_path = '/' # 获取路径下文件 dir_list = os.listdir(dir_path) # 获取文件数量 dir_nums = len(dir_list) # 遍历替换文件名 i = 1 for dir in dir_list: if dir.endswith('.下载'): # os.rename需要文件路径 # 去掉'.下载' new_name = dir[:-3] old_di

Node.js aitaotu图片批量下载Node.js爬虫1.00版

即使是https网页,解析的方式也不是一致的,需要多试试. 代码: //====================================================== // aitaotu图片批量下载Node.js爬虫1.00 // 2017年11月14日 //====================================================== // 内置http模块 var https=require("https"); // 内置文件处理模块,