HTTP 知多少 - 内容分配(文件下载)
HTTP知多少——Content-disposition(文件下载)
HTTP知多少——Content-Type(内容类型)详解
Content-disposition(内容-部署)是MIME协议类型的扩展,MIME协议指示MIME用户代理如何显示附加的文件。
1. Content-Disposition的作用
Content-disposition是MIME协议的扩展,MIME协议指示MIME用户代理如何显示附加的文件。当Internet Explorer接收到头时,他会激活文件下载
对话框,它的文件名框自动填充headers指定的文件名。
服务器向浏览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt
、jpg
等。如果需要提示用户保存,就要利用Content-Disposition
进行处理,(敲黑板,划重点)关键在于一定要加上attachment
[附件] [əˈtætʃmənt]
。
例如
Response.AppendHeader("ContentDisposition","attachment;filename=FileName.txt");
这样的话,浏览器在打开的时候回提示保存还是打开,即使选择打开,也会使用相关联的程序,比如记事本打开,而不是IE直接打开。
Content-Disposition就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名。
具体的定义如下:
//content-disposition的定义
content-disposition ="Content-Disposition" ":"
disposition-type
*(";" disposition-param)
//disposition-type的定义
disposition-type="attachment"|disp-extension-token
//disposition-param的定义
disposition-param=filename-param|disp-extension-parm
//filename-param的定义
filename-param= "filename" "=" quoted-string
//disp-extension-token的定义
disp-extension-token = token
//disp-extension-parm
token "=" ( token | quoted-string )
例如:
Content-Disposition:attachment;filename="filename.xlsx;"
注意点:
当然filename参数可以包含路径信息,但User-Agnet会忽略这些信息,只会把路径信息的最后一部分作为文件名。当响应类型为application/octet-stream
情况下使用上面的头信息的话,那么就不能直接显示内容,而是弹出一个"文件下载"的对话框,接下来就是用户决定“打开”还是“保存”了。
2. 下载文件中文乱码
Content-Disposition如何适配各个浏览器以及解决中文乱码问题。
Content-Disposition如何适配各个浏览器以及解决中文乱码问题。
IE浏览器下载乱码问题
总体下来就是这么几点:
- 两个IE11在使用第一个方法下载文件时中文文件名都会乱码,而使用第二个方法下载时其中一个IE11中文不会乱码,另一个IE11则会乱码;
- 文件名中存在空格时两个IE11浏览器下载下来文件文件名空格会变成+号,其他浏览器没有这个问题;
- 火狐浏览器下载时遇到文件名中有空格时下载下来的文件的文件名第一个空格后面的文字都会丢失。
**老版IE的USER-AGENT参数中含有MISE关键字,但是IE11之后浏览器的USER-AGENT中去掉了MISE关键字。
【IE11:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko;】
**IE下载文件名存在+号,是因为URLEncoder函数在对字符串进行转码后将空格替换成了+号,IE直接把+号显示出来。解决办法就是对文件名进行转码之后,使用replace方法将+号替换成%20即可,浏览器会将%20转换成空格输出。
对于第三个问题则是因为代码在set响应头时Content-Disposition参数的attachment;filename=等号后面文件名字符串没有使用双引号括起来,火狐浏览器对于遇到文件名有空格时认为空格前的字符是一个完整的字符串。故下载下来文件时文件名就只剩空格前的那几个字了。解决办法就是:在filename两边加上双引号并加反斜杠转义。
编码类
public static String toUtf8String(String fileName, HttpServletRequest request) throws Exception {
final String userAgent = request.getHeader("USER-AGENT");
String finalFileName = null;
if (StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent, "Trident")) {// IE浏览器(旧版/新版)
finalFileName = URLEncoder.encode(fileName, "UTF8");
} else if (StringUtils.contains(userAgent, "Mozilla")) {// google,火狐浏览器
finalFileName = new String(fileName.getBytes(), "ISO8859-1");
} else {
finalFileName = URLEncoder.encode(fileName, "UTF8");// 其他浏览器
}
return finalFileName;
}
@RequestMapping("/downExcel")
public void downExcel(HttpServletRequest request, HttpServletResponse response) {
out = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
response.setHeader("Content-disposition",
"attachment; filename=" + ExcelUtil.toUtf8String(fileName, request) + ".xlsx");// 设定输出文件头
response.setContentType("application/msexcel");// 定义输出类型
//将数据写入输出流
//TODO
}
注意:下载的时候使用的Content-Type大全,一般可以使用application/octet-stream。
文章参考:
header中Content-Disposition的作用
下一篇: 文件下载的 HTTP 协议实现
推荐阅读
-
位、字节、WORD、DWORD 的区别和联系 - Unicode 和 ANSI 的区别就像输入法中 "全宽 "和 "半宽 "的区别一样。 由于不同的 ANSI 编码有不同的标准(不同的字符集),对于给定的多字节字符串,我们必须知道它使用的是哪种字符集,才能知道它包含哪些 "字符"。对于 UNICODE 字符串来说,无论环境如何,它所代表的 "字符 "内容始终是相同的。Unicode 有一个统一的标准,定义了世界上大多数字符的编码,因此拉丁文、数字、简体中文、繁体中文和日文都可以存储在一个编码中。统一码是一个统一的标准,定义了世界上大多数字符的编码。 比特(Bit)和字节(Byte)的区别:例如USB2.0 标准接口的传输速率为 480Mbps,有一些人误认为是每秒 480 兆比特,同样网络带宽为 2MB,就容易误认为是每秒 2 兆比特。其实,480Mbps 应该是 480 兆比特/秒或 480 兆字节/秒,它等于 "60 兆字节/秒";同样,2MB,应该是 256 兆字节/秒。 Bit 和 Byte 译为 "比特",都是数据计量单位,比特="位 "或 "比特"。 Byte = 字节,即 1byte = 8bits,两者的换算关系为 1:8。 Mbps = mega bits per second(兆位/秒)是速率单位,因此 2M 带宽应为 2 兆位/秒,即 2MBps。MB = 兆字节(Megabytes,兆字节)是单位量,1MB/S(兆字节/秒)= 8MBPS(兆字节/秒)。 通常所说的硬盘容量是指 40GB、80GB、100GB,其中的 B 是指 Byte 也称为 "字节"。 1 KB=1024 字节 1 MB=1024 KB=1024*1024 字节 1 GB=1024 MB=1024*1024*1024 字节 例如,以前所谓的 56KB MODEM 转换过来的 56KBps 除以 8 就是 7Kbyte,所以真正从网上下载文件存在硬盘上的速度也是每秒 7Kbyte;也就是说,用 B 表示传输速度一般指 Bit;用 B 表示容量一般指 Byte。比特、字节、WORD、DWORD 的本质。
-
iCloud 切换区域,中国区保留 appStore(更新)--自 2018 年 2 月 28 日起,中国区 iCloud 由云上贵州管理 苹果公司发布的公告 https://support.apple.com/zh-cn/HT208352 关键词 关键部分 受影响的 iCloud 账户:国家或地区设置为 "中国 "的 Apple ID。 iCloud 包含的服务照片、邮件、通讯录、日历、提醒事项、备忘、书签、钱包、钥匙串、云备份、云驱动器、应用程序数据 新条款和条件: 同意仅出于本协议允许的目的并在中国法律允许的范围内使用服务。 云桂洲在提供服务时应使用合理的技能并尽职尽责,但在适用法律允许的最大范围内,我们不保证或担保您通过本服务存储或访问的任何内容不会意外损坏、崩溃、丢失或根据本协议的条款被删除,如果发生此类损坏、崩溃、丢失或删除,我们不承担任何责任。您应自行负责维护您的信息和数据的适当备份。 Apple 和云上贵州有权访问您存储在服务中的所有数据,包括有权根据适用法律相互之间共享、交换和披露所有用户数据(包括内容)。 本协议的解释、效力和履行应适用*法律。对于因本协议引起的或与本协议有关的任何争议,云桂洲和您同意提交中国国际经济贸易仲裁委员会(CIETAC)根据提交仲裁时有效的法律在北京进行具有约束力的仲裁。 由云桂洲管理,用户选择: 停用; ID 到地区; 受 iCloud(由云桂洲运营)条款和条件约束 首先,我想说说我对数据安全的看法。 当我在朋友圈发布通知时,有些朋友回复说国外的操作并没有多安全,或者国外的安全只是相对于国外而言的等等。首先,我非常感谢这些朋友,这让我反思什么是数据安全。以下观点均属个人观点: 国外的月亮一定比国内圆? 这是一个根深蒂固的问题,只要有人说国外的东西比国内好,就会有人嘲笑崇洋媚外。我觉得我们在某些方面应该向国外学习,比如搜索引擎和版权问题。打开百度搜索 "数据安全",第一行肯定是广告。打开谷歌搜索 "数据安全",第一条就是 "数据安全_百度百科" .....各种版权问题大家都明白,支持正版,但不仅客户一心想找免费破解,就连作者也往往没有保护自己劳动成果或产品的想法。但从另一个层面来说,国内的发展和安全,甩国外几条街。没有说哪里好,哪里不好,辩证地去学习更好。 国外也有别有用心的数据泄露,谈何安全? 从加密解密的角度看,自古以来就没有绝对安全的加密,只有相对安全的做法。苹果的棱镜门、微软的 cpu 漏洞,各种参差不齐的被破解案例 ....是的,这的确是一个很好的论据,但凡事都不能只看一面,当年苹果面对FBI破解手机的要求,几经论证,苹果还是拒绝破解。这点拿到国内,只要上面的文件传达下去,还有企业敢说不吗?还敢说不吗? 关于这次iCloud数据迁移个人看法? 把数据迁移到贵州的云端,相当于把手机的所有数据都存储在贵州的云端服务器上。也许访问数据的速度会快很多,但我会把我的iCloud区放到美国,因为我不想数据存在云上贵州后经常接到莫名其妙的电话或短信,更不想因为乱用国外服务器而被请去喝茶。iCloud一个ID,即从中国账号转到美国区,主要用于数据存在美国服务器上。appStore一个ID,除了注册一个中国ID外,专门用来下载应用用,因为国外ID不支持酷狗和网易云等应用。麻烦的是,用了新的 appStore ID 后,当前的应用还得重新下载安装,因为旧的应用 ID 与新的应用 ID 不兼容,安装不了。最后,iCloud迁移后,国内用户使用美国服务器,估计要 "扶墙 "了。 专业步骤: 首先,进行appleID设置,这是前提条件,否则无法选择转移区域! 取消 appleID 的双重认证 取消家庭共享选项 二、窗口下载并安装 icloud 3.0 版
-
用 linux 命令行从 http 下载内容
-
内容-处置 文件上传、下载 中文乱码 HTTP 标头解决方案 - 文件下载
-
C# 实现 HTTP 下载文件方法
-
Http 文件下载、速度限制和间歇性传输
-
HTTP 协议下载文件响应设置
-
Http 文件上传和下载
-
java 读取 http 路径下载文件
-
java http 下载文件发布