超详细的实现下载文件功能教程,文件下载实现。

by img Microanswer 创建时间:Oct 14, 2019 11:32:46 AM 

标签: java 文件下载 下载文件 Content-Disposition



重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

文件下载功能对任何项目来说基本上是一个刚需。本文将详细的介绍如何实现文件下载功能。注意,文件下载有涉及后台的部分,本文将以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协议规范是非常迫切的一项技能。

全文完, 转载请注明出处。 对你有帮助?不如赞一个吧:
发表评论(发表评论需要登录,你现在还没有登录。)
你需要先登录才可以评论。

评论列表 (0条)