后台经常有查看图片的功能,可以使用springMVC异步获取图片流并显示在页面上。
前台js(这里使用easyui的弹出来实现点击后右下角滑出图片预览看效果的功能):
<span style="white-space:pre"> </span>//获取图片并显示出来
function showImg(imgName,top_id){
$.messager.show({
title:'图片预览',
width: 240,
height:200,
showSpeed:500,
msg:'<img src="getPic.do?top_id='+top_id+'&imageName='+imgName+'" style="max-width:230px;"/>'
});
}
controller层:
<span style="white-space:pre"> </span>/**
* 获取图片
*/
@RequestMapping(value="/getPic.do")
private Object topicGetPic(HttpServletRequest request, HttpServletResponse response,String imageName) throws Exception{
if(imageName==null){
return null;
}
//图片名称验证(防止任意文件下载的漏洞)
if(!ImageUtil.checkName(imageName)){
response.getWriter().write("非法名称");
return null;
}
String absolute_path = Constant.URL_BASE_IMG_COLUMN + File.separator + imageName;
ImageUtil.getImageToResponse(response, absolute_path);
return null;
}
其中的getImageToResponse方法如下:
<span style="white-space:pre"> </span>/**
* 根据绝对路径将图片留写入response中
*/
public static void getImageToResponse(HttpServletResponse response,String absolute_path){
try{
FileInputStream hFile = new FileInputStream(absolute_path); // 以byte流的方式打开文件 d:\1.gif
int i=hFile.available(); //得到文件大小
byte data[]=new byte[i];
hFile.read(data); //读数据
response.setContentType("image/*"); //设置返回的文件类型
OutputStream toClient=response.getOutputStream(); //得到向客户端输出二进制数据的对象
toClient.write(data); //输出数据
toClient.flush();
toClient.close();
hFile.close();
}catch(Exception e){}
}
关于任意文件下载的漏洞问题:
在上面的controller中有这么一段判断:
<span style="white-space:pre"> </span>//图片名称验证(防止任意文件下载的漏洞)
主要是需要对文件的名称和路径要做正则的判断(去除系统命令和文件类型验证),防止任务文件下载的漏洞。
例如如果图片名称叫:../../../../../../../../+文件系统下的任意路径+文件名。这样就可能获取到服务器上的文艺文件。
处理方法:1.使用数据库存图片,获取直接从数据库中获取
2.如果是使用系统图片,路径和文件名需要进行验证