因为听到有同事讨论JSP输出Excel文件的,就是在页面上有一个【导出】按钮,能够将查询结果导出到Excel文件让用户下载。有人说要用POI在后台生成临时的Excel文件,然后通过读取FileStream写入到OutputStream来解决。其实这个功能不需要这么重型的武器的,虽然很多人讨厌MS,但是不得不承认MS绝对不是乱盖的,IE和Office产品的几近完美的结合就是一个列子。页面里面的Table很容易就可以导出到Excel文件,而且格式都能够完好的保存,所以如果要将查询结果导出到Excel,只需将页面的Context-Type修改一下就可以了:

<%@ page language="java" contentType="application/vnd.ms-excel"%>

然后请求这个页面的时候,就会出现这样的IE窗口:

看到上面的菜单了么?除了IE的,还有Excel的。而且在点击“文件”->“另存为”的时候,如果选择“Excel工作簿”,那么保存的文件就是真正的转换到Excel文件的存储格式了。

不过,有一个问题是,如果我不希望直接在IE里面打开Excel文件,我希望能够提供那个打开/保存的对话框,应该如何做?

模模糊糊记得很久很久以前用过一个参数,于是乎,google一下吧,找到了,就是这个Content-Disposition参数,HTTP Response Header的一个参数。但是这个不是标准参数,查看一下HTTP/1.1的规范文档,对于这个参数的解释大意如下:

Content-Disposition参数本来是为了在客户端另存文件时提供一个建议的文件名,但是考虑到安全的原因,就从规范中去掉了这个参数。但是由于很多浏览器已经能够支持这个参数,所以只是在规范文档中列出,但是要注意这个不是HTTP/1.1的标准参数。

于是,在页面加入一行代码:

<%
response.addHeader("Content-Disposition", "attachment;filename=test.xls");
%>

能够看到“文件下载”的对话框了:

测试了一下,其实IE是根据Content-Disposition中filename这个段中文件名的后缀来识别这个文件类型的,所以,如果有很多种文件类型的时候,可以将Content-Type设置为二进制模式的:

<%@ page language="java" contentType="application/octet-stream"%>

附Content-Disposition的解释:

19.5.1 Content-Disposition The Content-Disposition response-header field has been proposed as a means for the origin server to suggest a default filename if the user requests that the content is saved to a file. This usage is derived from the definition of Content-Disposition in RFC 1806 [35].

content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) 
disposition-type = "attachment" | disp-extension-token 
disposition-parm = filename-parm | disp-extension-parm 
filename-parm = "filename" "=" quoted-string 
disp-extension-token = token 
disp-extension-parm = token "=" ( token | quoted-string )

An example is 
    Content-Disposition: attachment; filename="fname.ext"

The receiving user agent SHOULD NOT respect any directory path information present in the filename-parm parameter, which is the only parameter believed to apply to HTTP implementations at this time. The filename SHOULD be treated as a terminal component only.

If this header is used in a response with the application/octet- stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog.

Content-Disposition中文乱码

Response.setHeader(”Content-Disposition”, “attachment; filename=” + fileName+”.xls”);
如果file.Name为中文则乱码。解决办法是
方法1:
response.setHeader(”Content-Disposition”, “attachment; filename=” + java.net.URLEncoder.encode(fileName, “UTF-8″));
下载的程序里有了上面一句,一般在IE6的下载提示框上将正确显示文件的名字,无论是简体中文,还是日文。但是文字只要超过17个字,就不能下载了。
一. 通过原来的方式,也就是先用URLEncoder编码,当中文文字超过17个时,IE6 无法下载文件。这是IE的bug,参见微软的知识库文章 KB816868 。原因可能是IE在处理 Response Header 的时候,对header的长度限制在150字节左右。而一个汉字编码成UTF-8是9个字节,那么17个字便是153个字节,所以会报错。而且不跟后缀也不对.

方法2:
response.setHeader( “Content-Disposition”, “attachment;filename=” + new String( fileName.getBytes(”gb2312″), “ISO8859-1″ ) );
在确保附件文件名都是简体中文字的情况下,那么这个办法确实是最有效的,不用让客户逐个的升级IE。如果台湾同胞用,把gb2312改成big5就行。但现在的系统通常都加入了国际化的支持,普遍使用UTF-8。如果文件名中又有简体中文字,又有繁体中文,还有日文。那么乱码便产生了。另外,在上Firefox (v1.0-en)下载也是乱码。

本文我们来说一下MIME 协议的一个扩展Content-disposition。

我们在开发web系统时有时会有以下需求:

  • 希望某类或者某已知MIME 类型的文件(比如:*.gif;*.txt;*.htm)能够在访问时弹出“文件下载”对话框
  • 希望以原始文件名(上传时的文件名,例如:山东省政府1024号文件.doc)提供下载,但服务器上保存的地址却是其他文件名(如:12519810948091234_asdf.doc)
  • 希望某文件直接在浏览器上显示而不是弹出文件下载对话框
  • ……………………

要解决上述需求就可以使用Content-disposition来解决。第一个需求的解决办法是

Response.AddHeader "content-disposition","attachment; filename=fname.ext" 将上述需求进行归我给出如下例子代码:public static void ToDownload(string serverfilpath,string filename)
{
FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
long fileSize = fileStream.Length;
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";");
attachment --- 作为附件下载
inline --- 在线打开
HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
byte[] fileBuffer = new byte[fileSize];
fileStream.Read(fileBuffer, 0, (int)fileSize);
HttpContext.Current.Response.BinaryWrite(fileBuffer);
fileStream.Close();
HttpContext.Current.Response.End();
}

public static void ToOpen(string serverfilpath, string filename)
{
FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
long fileSize = fileStream.Length;
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=\"" + UTF_FileName(filename) + "\";");
HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
byte[] fileBuffer = new byte[fileSize];
fileStream.Read(fileBuffer, 0, (int)fileSize);
HttpContext.Current.Response.BinaryWrite(fileBuffer);
fileStream.Close();
HttpContext.Current.Response.End();
}

private static string UTF_FileName(string filename)
{
return HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8);
}

简单的对上述代码做一下解析,ToDownload方法为将一个服务器上的文件(serverfilpath为服务器上的物理地址),以某文件名 (filename)在浏览器上弹出“文件下载”对话框,而ToOpen是将服务器上的某文件以某文件名在浏览器中显示/打开的。注意其中我使用了 UTF_FileName方法,该方法很简单,主要为了解决包含非英文/数字名称的问题,比如说文件名为“衣明志.doc”,使用该方法客户端就不会出现 乱码了。

需要注意以下几个问题:

  1. Content-disposition是MIME协议的扩展,由于多方面的安全性考虑没有被标准化,所以可能某些浏览器不支持,比如说IE4.01
  2. 我们可以使用程序来使用它,也可以在web服务器(比如IIS)上使用它,只需要在http header上做相应的设置即可

转载于:https://www.cnblogs.com/vinozly/p/4915374.html

【转】HTTP Response Header 的 Content-Disposition相关推荐

  1. nginx 错误502 upstream sent too big header while reading response header from upst

    原文参考:http://hi.baidu.com/wastorode/item/ec86ade6ac0af7a2c10d75f4 sudo gedit /var/log/nginx/error.log ...

  2. 在nginx中用X-Accel-Redirect response header控制文件下载

    2019独角兽企业重金招聘Python工程师标准>>> 在web应用中,常常会有文件需要下载.如果这些文件是非常私密的,直接用web服务器下载,就不能检查文件的下载权限.以往遇到这种 ...

  3. 接口响应的Response Header打印不出全部值问题

    后端在每一次接口请求成功时都会更新token值,会在response header中返回.前端在HTTP请求拦截统一处理,每次都会更新vuex store里的用户信息. 但是 在打印时发现,我的电脑打 ...

  4. 已解决,软件V2报错 failed to read response header > websocket: close 1005 (no status)问题

    软件V who-you-know 本帖仅供学习参考,请勿讨论软件和V问题,发现会删除并举报,遵纪守法人人有责,谢谢. error : 23:37:05 tcp:127.0.0.1:55901 acce ...

  5. 浏览器返回数据量过大报‘failed to load response data: Request content was evicted from inspector cache’

    主要参考:failed to load response data request content was evicted from inspector cache 现象: 解决方法: copy as ...

  6. Response Header里的Server,X-Powered-By,X-AspNet-Version字段等敏感信息删除

    Response Header里的Server,X-Powered-By,X-AspNet-Version字段等敏感信息删除   简介 通过抓包工具burpsuite或者fiddler抓取分析resp ...

  7. 浏览器的Response Header

    浏览器的Response Header 常见的请求头和响应头: 请求: 客户端->服务器 request GET请求方式 Accept: 客户端能接收的资源类型 Accept-Language: ...

  8. recv() failed (104: Connection reset by peer) while reading response header from upstream

    场景:为了得到用户在线等实时信息,在客户端做了个ajax轮训,每隔5秒请求一次: 用户量一上来,于是问题就来了,页面各种卡nginx日志文件 [root@iZt web]# tail -f /data ...

  9. nginx响应超时upstream timed out (110: Connection timed out) while reading response header from upstream

    问题描述 解决方法 提高nginx网络吞吐量buffers优化指令说明 nginx代理超时配置 nginx缓存区大小设置 问题描述 后台server服务响应时间正常,但是请求没有打到服务器,在ngin ...

最新文章

  1. 揭露男生的真实心理年龄测试软件,心理年龄测试
  2. Refused to display http localhost8080 xxx‘in a frame because it set ‘X-Frame-Options‘ to ‘DENY‘
  3. 计划将项目中使用entity framework的要点记录到改栏目下
  4. c语言程序设计考试改革,C语言程序设计课程考试改革实施方案.pdf
  5. 字符串查找KMP算法(转)
  6. python正则匹配空格+数字+空格_详解Python中正则匹配TAB及空格的小技巧
  7. maven clean警告:The requested profile “pom.xml“ could not be activated because it does not exist
  8. PHP面向对象构造函数,析构函数
  9. 吴恩达神经网络和深度学习-学习笔记-11-Momentum梯度下降法
  10. 通过HTTP协议发送远程消息
  11. poj 1032 Parliament 编程的小技巧
  12. abb变频器580系列改中文_ABB变频器ACS580系列
  13. linux adobe flash 安装,Ubuntu 12.10下为Firefox安装Adobe Flash Player
  14. 三星线刷工具Odin3_V3.12.7
  15. idea手动执行maven命令的三种方式
  16. WordPress站点上传文件插件WordPress File Upload
  17. altium designer PCB各层介绍+添加多层+设置正/负片+设置层的网络标号
  18. 《软件系统架构:使用观点和观点与利益相关者合作》阅读小结——一
  19. Mac小技巧—如何查看 Mac 的关机和重启历史
  20. JavaScript富应用MVC MVVM框架

热门文章

  1. 用SignalR 2.0开发客服系统[系列3:实现点对点通讯]
  2. C++ Prime:switch内部的变量定义
  3. HDU 2504 又见GCD
  4. 为什么说Lucene不好
  5. 【Java架构:持续交付】一篇文章搞掂:持续交付理论
  6. Python之迭代器和生成器
  7. c++值传递,指针传递,引用传递以及指针与引用的区别
  8. LeetCode Range Addition II
  9. 游戏中每日刷新实现思路浅析
  10. MySQL索引使用方法和性能优化