TAT.iAzrael 在浏览器端用 JS 创建和下载文件
In 未分类 on 2014年01月03日 by view: 106,718
42

前端很多项目中,都有文件下载的需求,特别是 JS 生成文件内容,然后让浏览器执行下载操作(例如在线图片编辑、在线代码编辑、iPresst 等)。

但受限于浏览器,很多情况下我们都只能给出个链接,让用户点击打开-》另存为。如下面这个链接:

<a href="file.js">file.js</a>

用户点击这个链接的时候,浏览器会打开并显示链接指向的文件内容,显然,这并没有实现我们的需求。

HTML5 中给 a 标签增加了一个 download 属性,只要有这个属性,点击这个链接时浏览器就不在打开链接指向的文件,而是改为下载(目前只有 chrome、firefox 和 opera 支持)。

QQ20140102-2

下载时会直接使用链接的名字来作为文件名,但是是可以改的,只要给 download 加上想要的文件名即可,如:download=“not-a-file.js”。

QQ20140102-3

Not enough!

但是这样还不够,以上的方法只适合用在文件是在服务器上的情况。如果在浏览器端 js 生成的内容,想让浏览器进行下载要如何办到呢?

其实还是有办法办到的,相信很多人都多少听过了 DataURI 这个词,比较常见的就是图片的 src,如:

<img src="data:image/gif;base64,R0lGOXXXXX">

DataURI 的解释可以移步这里,本人就不在解释了。

那么,现在要将 js 生成的内容进行下载就有法可依了。封装成一个方法如下:

调用 downloadFile 之后,用户点击链接,就能触发浏览器下载。

Not enough!

但是,还不够,上面的办法有两个硬伤,会导致流失很多懒人美眉:

  1. 下载的文件类型限制死了,美眉要下载处理后的果照怎么办?
  2. 下载还要再点击一下,太麻烦啦。

要解决文件类型的问题,可以用浏览器的新 API(URL.createObjectURL)来解决问题,URL.createObjectURL 通常都是用来创建图片的 DataURI 用来显示图片,这里用来下载文件,让浏览器来帮我们设定好文件类型。

URL.createObjectURL 的参数是 File 对象或者 Blob 对象,File 对象也就是通过 input[type=file] 选择的文件,Blob 对象是二进制大对象,详细说明可参考这里

现在,我们只要用 content 创建一个 ObjectURL 并赋值给 aLink 即可解决文件类型的限制问题。

文件的自动下载也挺好办,自己构建一个 UI 点击事件,再自动触发下,就能实现自动下载啦。

现在来看看最终代码:

现在,只要一调用 downloadFile,文件就自动下载了,是不是很爽咧,^_^。

注:目前(2014-01-02)Blob 和 URL.createObjectURL 在标准浏览器里面都不再需要加私有前缀,可以放心使用啦啦啦~~如果你不放心,可以查查 Can I Use

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2014/01/use-js-file-download/

  1. ss 2018 年 1 月 9 日

    确实已经不能用了。。。。

  2. lebron112 2017 年 10 月 26 日

    目前不能使用了 我是 content 转了一个 由 canvas 生成的=》canvas.toDataURL( “jpg” )
    下载后的文件很大,而且不能显示

  3. 你好 2017 年 7 月 7 日

    你好,我问下,这个把图片下载到哪里去了?

  4. zhy 2017 年 4 月 10 日

    已失效,m53 chrome

    • zhy 2017 年 4 月 10 日

      还是又参考价值 – –

  5. 蓝鹏马 2016 年 12 月 27 日

    请问能获取用户选择保存的路径吗

  6. Javascript下载页面内容成文件 - 歪麦博客 2016 年 12 月 13 日

    […] 在浏览器端用 JS 创建和下载文件 […]

  7. 苇荡 2016 年 11 月 14 日

    华为手机浏览器不支持 download

  8. 哈哈大侠 2016 年 9 月 29 日

    文件太大 (>3MB) 基本都会触发 bug 提示网络错误无法下载

  9. 楚sirormy 2016 年 9 月 24 日

    然而并没有提到到底 content 是个什么东西

  10. nodejs-user 2016 年 8 月 23 日

    如何指定下载编码?

发表评论到 lebron112