admin管理员组文章数量:1537955
解决ie打开本该下载的文件问题
背景:
上周项目出现了一个bug,一般下载直接写个如下的<a>标签即可
<a href="https://caomei.mall/files/1/5/files/menu.pdf">download</a>
然而发现.txt,.jpg和.pdf等格式的文件会在浏览器直接打开而不是下载.然后百度到w3cSchol.<a>标签有一个download属性.
<a href="/images/myw3schoolimage.jpg" download="w3logo">
官方解释:
定义和用法
download 属性规定被下载的超链接目标。
在 <a> 标签中必须设置 href 属性。
该属性也可以设置一个值来规定下载文件的名称。所允许的值没有限制,浏览器将自动检测正确的文件扩展名并添加到文件 (.img, .pdf, .txt, .html, 等等)。
然而兼容性并不好,崩溃,我可是要支持ie的人儿啊.
继续搜索,终于,修改response的头部信息,将文件内容读取写出输出流
@RequestMapping(value = "/downFile", method = RequestMethod.POST)
@ResponseBody
public void downFile(HttpServletRequest request, HttpServletResponse response, String fileUrl) {
try {
// path是指欲下载的文件的路径。
File file = new File(fileUrl);
// 取得文件名。
String filename = file.getName();
// 取得文件的后缀名。
//String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(fileUrl));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
response.addHeader("Content-Length", "" + file.length());
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
outputStream.write(buffer);
outputStream.flush();
outputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
然而测试妹纸马上就叫我了,.avi格式的文件下载失败了,吓得我赶紧去线上瞅瞅,内存溢出了
不禁感叹,这小小的下载事情真多.
继续查找原因,发现这种方式下载小一点的文件,或者服务器配置高一点看不出啥来,但是当要下载的文件很大的时候,将字节数组吃进内存,系统运行就会GG了.
所以,一点点的将内容写进内存咯,测试okay.
@RequestMapping(value = "/downFile", method = RequestMethod.GET)
@ResponseBody
public void downFile(HttpServletRequest request, HttpServletResponse response, String fileUrl) {
try {
Video v = new Video();
v.setRelname(fileUrl);
Video video = videoService.selectOne(v);
String path = GlobalData.FTP_BASEPATH + File.separator + video.getPath() + File.separator + video.getRelname();
// path是指欲下载的文件的路径。
File file = new File(path);
// 取得文件名。
String filename = video.getName();
//filename转码,解决中文文件名的问题
response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(filename.getBytes("GB2312"), "ISO_8859_1")+"\"");
response.setHeader("Content-Length", "" + file.length());
//告诉浏览器数据是二进制流
response.setContentType("application/octet-stream");
// 以流的形式下载文件。
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(path));
byte[] b = new byte[1024];
int length = 0;
OutputStream out = response.getOutputStream();
while ((length = fis.read(b))>0){
out.write(b, 0, length);
}
fis.close();
out.close();
} catch (IOException ex) {
logger.error("下载文件失败:",ex);
}
}
网上提示,还可以使用org.springframework.util.FileCopyUtils修改原来的代码,和上述代码的内部实现差不多.使用了分块的方式进行流复制,并在完成后关闭流,实现类似我们一般的上传处理。
FileInputStream is = new FileInputStream(new File(filePath));
response.setContentLength(is.available());
FileCopyUtils.copy(is, response.getOutputStream());
本文标签: 文件
版权声明:本文标题:解决ie打开本该下载的文件问题 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1726426812a1070479.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论