浏览 2193 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-11
这个问题只出现在ie8下.对于其他浏览器都显示正常. 试着将报表图片的地址直接在ie中访问 引用 /preview?__sessionId=20110911_170334_597&__imageid=custom1666453a13257b916471.png ie会弹出一个文件然你下载,将下载的文件改成xxx.png后图片正常显示. 由此可见ie8没有正确解析资源. 联想到前几天对apache做了安全加固,打了一个防止xss漏洞的配置. 会不会是这个引起的呢?配置如下: 引用 <IfModule mod_headers.c> Header set X-Content-Type-Options "nosniff" Header set X-XSS-protection "1;mode=block" RequestHeader unset Range </IfModule> 将这个配置去掉后,图片可以正常显示.于是可以认定是配置引起的这个故障. 但是为什么会引起这个故障呢? 而且安全配置是不能修改的,所以要解决这个问题我们就必须要从别的方面来着手. 先让我们看看apache干了点什么吧! 这段配置主要是防止xss攻击的 引用 XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常忽略其危害性。 做了这个配置后,如果是ie8访问,apache会自动在请求头上加上 X-Content-Type-Options "nosniff" X-XSS-protection "1;mode=block" 这两个配置. 第一个配置是告诉浏览器,如果遇到未知文件类型,不要去自动解析. 问题就出在这了,birt对于图片的请求content_type返回的是个image的值,这个值ie8是无法确定解析类型的,如果允许ie8自动分析文件确定解析图片,那么图片是可以正常显示的,但是禁止后,ie8无法确定的文件类型就不会再解析,页面上就会显示一个红叉叉. 既然已经了解了前因后果,那么只要做出相对应的操作,就可以解决这个问题. 最开始的想法是在filter中设置一下response,将content-type设置为image/x-png 但是发现这么做无效,浏览器返回的response还是image类型. G了一下,发现了这么一段话. 引用 response.setContentType指定 HTTP 响应的编码,同时指定了浏览器显示的编码. response.setCharacterEncoding设置HTTP 响应的编码,如果之前使用response.setContentType设置了编码格式,则使用response.setCharacterEncoding指定的编码格式覆盖之前的设置.与response.setContentType相同的是,调用此方法,必须在getWriter执行之前或者response被提交之前. 看来在别的地方contenttype已经被修改过了,而且随后还调用了getwrite. 莫有办法,只好一步步的dug了,顺藤摸瓜.让我发现了这么一段. /************************************************************************************* * Copyright (c) 2004 Actuate Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Actuate Corporation - Initial implementation. ************************************************************************************/ package org.eclipse.birt.report.service.actionhandler; import java.util.regex.Pattern; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.birt.report.context.IContext; import org.eclipse.birt.report.service.actionhandler.AbstractBaseActionHandler; import org.eclipse.birt.report.service.api.InputOptions; import org.eclipse.birt.report.soapengine.api.GetUpdatedObjectsResponse; import org.eclipse.birt.report.soapengine.api.Operation; import org.eclipse.birt.report.utility.ParameterAccessor; abstract public class AbstractRenderImageActionHandler extends AbstractBaseActionHandler { public AbstractRenderImageActionHandler( IContext context, Operation operation, GetUpdatedObjectsResponse response ) { super( context, operation, response ); } public void __execute( ) throws Exception { context.getResponse( ).setContentType( "image" ); //$NON-NLS-1$ String imageId = context.getRequest( ).getParameter( ParameterAccessor.PARAM_IMAGEID ); ServletOutputStream out; String docName = null;// TODO: Do we need document name? InputOptions options = new InputOptions( ); options.setOption( InputOptions.OPT_REQUEST, context.getRequest( ) ); out = context.getResponse( ).getOutputStream( ); getReportService( ).getImage( docName, imageId, out, options ); } } 很明显在第四十一行,contenttype为image就是在这个地方设置,然后再下面修改了response的流,所以之后再调用setContentType就无效了,于是试着在这个地方改造一下. HttpServletRequest request = context.getRequest(); String url = ((HttpServletRequest)request).getRequestURI()+"?"+((HttpServletRequest)request).getQueryString(); String agent = ((HttpServletRequest)request).getHeader("User-Agent"); String regx = "/sherry/preview\\u003F__sessionid=\\w+&__imageid=\\w+.png"; if(Pattern.matches(regx, url.toLowerCase())&&agent.indexOf("MSIE 8.0")!=-1){ context.getResponse( ).setContentType( "image/x-png" ); //for ie8 nosniffer bug }else{ context.getResponse( ).setContentType( "image" ); //$NON-NLS-1$ } 因为该bug只在ie8下存在,所以针对ie8做一些特别的处理,将其的content_type设置为image/x-png. 改完后测试,一切正常!!!正式不容易啊! 其实这个问题还蛮复杂的,涉及到了服务器,客服端,还有birt框架,解决这个问题一共花了我两天时间.汗一个~~~,反思一下,解决问题中还是犯了很多主观错误,走了很多弯路,其实只要最开始就分析好,半天就可以解决这个问题.修复bug的时候还是要细心. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |