今天在用户需求下加上了HTTPS的配置,在使用时发现,系统中有关struts2下载文件均会报错。网上找了下资料,如下转载一个:
-----------------------------------------------------------------------------------------
原文地址:
http://www.cnblogs.com/ggjucheng/archive/2011/12/31/2308774.html
现象
(1) 在IE6/7/8下,使用HTTPS下载/打开文件时,通过抓包发现文件已传输,但IE提示“Internet Explorer无法下载 *** (来自 ***)。Internet Explorer无法打开该Internet站点。请求的站点不可用,或找不到。请以后再试。” ("Unable to download. Internet Explorer was unable to open this site. The requested site is either unavailable or cannot be found. Please try again later."),下载失败。
(2) 如果下载目标有一个hyperlink,当右键选择“目标另存为...”时,提示“Internet Explorer无法下载 *** (来自 ***)。无法将文件写入高速缓存”("The file could not be written to the cache"),下载失败。
原因
参考Microsoft KB815313316431812935323308
解决方法
(1) 参考上述MS KB,向client注册表增加下列DWORD条目BypassSSLNoCacheCheck,值设为1;
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\BypassSSLNoCacheCheck
下载reg
(2) 如果不方便修改client端,检查服务器端相关程序(eg. httpd),看是否在HTTP response header中自动添加了“Pragma: no-cache”等内容。(参考 MS KB316431的“更多信息”(More Information)部分)
以上2种解决方案皆可行,已经过验证。
原文出至http://rivercoolcool.spaces.live.com/blog/cns!D6F05428A2B8CB48!1494.entry?wa=wsignin1.0&sa=287780771
同类文档说明
1.http://support.microsoft.com/default.aspx/kb/316431/
2.http://topic.csdn.net/u/20080723/13/2b3f6922-b48e-41ba-80b7-021aed1b932a.html
-----------------------------------------------------------------------------------------
补充:以下是我参考网上的资料后再有一点实际运用的补充;
网上有一种方法是这样:
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
其实这个直接加载JSP页面中是没有用的,我尝试了一下,没有发现能解决问题,后来我的解决方案是:
在struts2 下载文件的Action或者是Servlet中加入:
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
这样就可以了,原理是什么我就没怎么详细说明了。至少我直接加在页面发现没有效果的。
还有就是这个问题暂时只发现只出现在IE中,火狐没有问题的。原因如我上面转载的文件一样。微软官方也有一定的解释的。可以去了解一下哦。
然而上述方法是一种,还有一种个人觉得就比较暴力了,不是很推荐,不过也算是一种解决办法。
方案就是写一个拦截器,将所有的response都加上上面这种方法,一劳永逸咯。
1: package com.datadriver.common.filter;
2:
3: import javax.servlet.*;
4: import javax.servlet.http.*;
5:
6: import org.apache.struts2.ServletActionContext;
7:
8: import java.io.IOException;
9:
10: public class HTTPSFilter implements Filter {
11:
12: public void destroy() {
13:
14: }
15:
16: public void doFilter(ServletRequest request, ServletResponse response,
17: FilterChain chain) throws IOException, ServletException {
18:
19: HttpServletRequest httpServletRequest = (HttpServletRequest) request;
20: HttpServletResponse httpServletResponse = (HttpServletResponse) response;
21:
22: // 通过https或http访问时
23: if (httpServletRequest.getScheme() == "https" || httpServletRequest.getScheme() == "http") {
24: httpServletResponse.setHeader("Content-Transfer-Encoding", "binary");
25: httpServletResponse.setHeader("Cache-Control",
26: "must-revalidate, post-check=0, pre-check=0");
27: httpServletResponse.setHeader("Pragma", "public");
28: }
29:
30: chain.doFilter(request, response);
31:
32: }
33:
34: public void init(FilterConfig filterConfig) throws ServletException {
35:
36: }
37:
38: }