重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。
文件下载功能对任何项目来说基本上是一个刚需。本文将详细的介绍如何实现文件下载功能。注意,文件下载有涉及后台的部分,本文将以java后台做介绍。如果你不是使用的java,没有关系。本文将带你了解下载的实现原理,了解了之后无论什么后台语言,都能够同样使用这个原理。
一、如何才能开始下载?
实际上你的每一次浏览器访问行为,都是在下载数据。只是当你打开的是一个html页面时,浏览器自己清楚这是你要立即观看的界面,而不是一个要另存为的文件,即便这样,当你右击页面,选择另存为时也依然会弹出目录让你选择一个位置来保存这个页面。
我们要做的事情就是,让浏览器不要去管返回的数据,而是自动弹出一个文件保存弹框出来。
这是由http协议的head控制的。Content-Disposition
字段表示了这是一个下载响应,通常针对下载响应,浏览器则会弹出文件保存框。因此,要实现下载文件的功能,你只需要在返回数据时,为其head中返回合适的 Content-Disposition
内容,就可以开始下载了。
如果对http协议还不是很了解,可以先阅读《【HTTP,Java】认识HTTP协议,在互联网世界里翱翔。》。
二、Content-Disposition
Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。当 Internet Explorer 接收到头时,它会激活文件下载对话框,它的文件名框自动填充了头中指定的文件名。(请注意,这是设计导致的;无法使用此功能将文档保存到用户的计算机上,而不向用户询问保存位置。)。
它的值必须是有一定的格式的,不可以随便乱写。它的值分为2部分,不妨先看图了解下:
如果要进一步了解此字段,可以查看规范 RFC6266。
在下载文件的同时,告诉浏览器文件类型,也是非常有必要的。因此,在响应头里,常常还会有 Content-Type
来说明文件的类型。
三、触发下载
有了以上知识,我们便可以轻松的实现下载链接(下文介绍)。现在要触发下载,只需要浏览器打开这个下载链接便可以完成。通常可以通过下面的方式来触发。
1、使用a标签
a标签是链接跳转的标准标签。但如果你的链接是一个下载链接,不用担心页面会被重新覆盖,下载链接只会弹出保存提示,而对页面没有影响。
<a href="https://xxx.xxx.xxx/download.mp3">点击下载</a>
2、使用JavaScript
在js里只需要为href赋值即可完成:
window.location.href="https://xxx.xxx.xxx/download.mp3";
四、下载链接(下载接口)实现
实际上大多数下载链接,我们都是不需要写的,因为多数情况下文件使用了类似七牛云来托管,只要上传了文件,下载链接就已经自动帮你生成好了。而有些场景,比如导出系统自己的业务数据为文件。这种需求来了的时候,不得不动手来实现一个可以下载的后台接口了。
下面示列一个下载接口:
// 典型的一个下载接口。
@RequestMapping(value = "/downloadFile")
public void downloadSysFile(HttpServletResponse response) throws Exception{
// 拿到响应输出流
ServletOutputStream outputStream = response.getOutputStream();
// 构建要输出给客户端的数据
File f = new File("D:/testfile.mp3");
// 设置响应数据需保存为文件,同时指定下载信息。
response.setContentType("audio/mp3");
response.setContentLengthLong(f.length());
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("UTF-8", f.getName()));
// 典型的流操作代码
FileInputStream fi = new FileInputStream(f);
byte[] data = new byte[1024];
int dataSize = 0;
while ((dataSize = fi.read(data)) != -1) {
outputStream.write(data, 0, dataSize);
}
outputStream.flush();
fi.close();
}
具体下载内容不同要根据自己的业务需求而定义。上述代码只是一个示列效果。
五、总结
互联网开发离不开http协议。这一切的功能实现都是基于http协议的了解。因此掌握http协议规范是非常迫切的一项技能。