js 选择图片并预览、上传

用火狐、谷歌调试图片的预览和上传可谓是怎么弄怎么行,只要你说出需求,但是到了IE下,就出现了各类各样的问题,可是无论你遇到什么样的问题,总会有解决的办法,尽管有时候办法可能会笨拙 、麻烦、费时、费力、很差看。html

选择图片固然很简单,用一个input file标签,点击就会弹出文件选择框。固然也不那么简单,每每咱们都嫌弃自带按钮很差看或是与你的操做逻辑不匹配,这就须要事件转移或者是按钮覆盖。哎,从何提及呢?
java

火狐、谷歌……数据库

页面中加入文件选择器标签,opacity:0使标签为透明,也能够display:none浏览器

<input type="file" id="choose-img" onchange="setImagePreview();" style="opacity:0">

将选择按钮的点击事件转移安全

button.onclick = function(){$("#choose-img").click()};

这样按钮的样式就能够彻底按你的喜爱来设置了,也能够是连接、div、随便服务器

文件选择器的onchange事件
app

function setImagePreview(event) {
    var imagechoose=document.getElementById("choose-img");
 /*   var fileName = imagechoose.value;  
    if (!fileName.match(/.jpg|.jpeg|.gif|.png|.bmp/i)) {  
        alert('您上传的图片格式不正确,请从新选择!');  
        return false;  
    }  */
    var imgObjPreview=document.getElementById("preview-img");    //预览图片的<img>
    
    if(imagechoose.files && imagechoose.files[0]){
    	var formData = new FormData();     // >=IE10 Partial support
    	formData.append("id",selectedId);
    	formData.append("file",imagechoose.files[0]);
        //火狐下,直接设img属性
        //imgObjPreview.src = imagechoose.files[0].getAsDataURL();

        //火狐7以上版本不能用上面的getAsDataURL()方式获取,须要一下方式
        imgObjPreview.src = window.URL.createObjectURL(imagechoose.files[0]);
    }
}

这样在页面上就能够看到用户选择的图片了,由于调用的是onchange事件,因此若是两次选择同一图片是不会调用这个方法的,由于没有change。函数

文件上传使用了简单方便的XMLHttpRequestpost

var xhrup = new XMLHttpRequest();
xhrup.open("POST", "后台接收路径");
xhrup.send(formData);    //上一个方法中保存的FormData,其余参数也能够一块儿传

也能够添加回调函数,XMLHttpRequest上传文件和请求文件都很好用ui

后台接收

@RequestMapping("/uploadImage")
public @ResponseBody void uploadImage(MultipartHttpServletRequest request,HttpServletResponse response)throws Exception {
	try{
		Map getMap = request.getFileMap();
		String id = request.getParameter("id");
		MultipartFile mfile = (MultipartFile) getMap.get("file");
		InputStream file = mfile.getInputStream();
		byte[] fileByte = FileCopyUtils.copyToByteArray(file);
		Map<String, Object> setMap = new HashMap<String, Object>();
		setMap.put("id",id);
		setMap.put("file", fileByte);
		bulletinService.uploadImage(setMap);    //保存到数据库
		operatelogService.addOperateLogInfo(request, "上传成功:成功上传图片");
	}catch (Exception e) {
		e.printStackTrace();
		operatelogService.addOperateLogError(request, "上传失败:服务器异常");
	}
}

IE9

下面就要一项一项地说说以上方法都是如何不行的了。

若是你给input file设成了display:none,那它必定没法给你弹出文件选择对话框了,设成opacity:0才免为其难能够了,若是你设了opacity:0仍是能看见,不妨重启机试试。

文件提交,不支持FormData格式,也获取不到文件的byte数据,因为它的安全机制,文件路径和文件数据对你来讲都是保密的,只能用form表单提交。提交后form的返回是一个页面,若是不想刷新页面,怎么办嘞,隐藏iframe。

事件转移,是能够的,不过,当你要提交表单的时候,它会检查表单要提交的内容,这一检查就检查出问题了,它认定你的input file不是用户选择赋值,而是js人为修改了它的值,因此在提交表单以前要清空你人为修改的东西,也就是说,你选了,它也让你选了,你要提交,它却把你选的东西清了再提交,后台什么也收不到。

这样事件转移就不能用了,可使用按钮覆盖的方法,很麻烦,很差调。把input file设成opacity:0,在其上覆盖你的按钮或其余,当用户点击你的按钮时,实际是点击到了input file的浏览按钮。固然,也能够直接用原生态的,就简单了。

再说说这个预览,刚开始我是用的获取文件的真实全路径,而后用滤镜显示。这个是能够的,但后来因为我不清楚的缘由,文件全路径获取不到了,简直坑死。

因此我用了将文件上传到服务器,再向服务器请求这个文件来显示。麻烦,稳妥。

IE滤镜预览图片

imagechoose.select();
imagechoose.blur();
 //       imgObjPreview.focus();
window.parent.document.body.focus();
//       window.top.document.body.focus();
var imgSrc = document.selection.createRange().text;    //这个理论上回获取到文件的全路径
 //       var imgSrc = $("#"+event.target.id).val();
        //必须设置初始大小
        imgObjPreview.style.width = ;
        imgObjPreview.style.height = ;
        //图片异常的捕捉,防止用户修改后缀来伪造图片
imgObjPreview.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
imgObjPreview.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;

form表单

<form action="后台接收路径" id="" target="隐藏iframe的name" method="post" enctype="multipart/form-data">
<input type="file" id="" onchange="">
</form>


input file的onchange事件

var uploadform = document.getElementById("包含input的表单的ID");
uploadform.submit();

后台接收

@RequestMapping("/uploadImage4ie")
public ModelAndView uploadImage4ie(@RequestParam("imgFile") MultipartFile imgFile,HttpServletRequest request,HttpServletResponse response)throws Exception {
	ModelAndView mav = new ModelAndView();
	mav.setViewName("返回页面"); 
	try{
		String imgId = request.getParameter("imgId");
		byte[] imgByte = imgFile.getBytes();

		String cuid = CUID.cuid(4);
		//文件保存路径
		String imagePath = (new File(this.getClass().getClassLoader().getResource("").toURI().getPath())).getParentFile().getParentFile().getPath()+"/images/docPreview/"+imgId+cuid+".jpg";
		FileImageOutputStream imageOutput = new FileImageOutputStream(new File(imagePath));
		imageOutput.write(imgByte, 0, imgByte.length);
		imageOutput.close();
		request.setAttribute("preId", imgId.substring(5));
		request.setAttribute("imgSrc", "images/docPreview/"+imgId+cuid+".jpg");
	        operatelogService.addOperateLogInfo(request, "上传成功:成功上传图片");
        }catch (Exception e) {
		e.printStackTrace();
		operatelogService.addOperateLogError(request, "上传失败:服务器异常");
	}
	return mav;
}

隐藏iframe

<iframe name='nofreshIframe' style='display: none;'></iframe>

在返回页面中设置预览<img>的src为请求图片路径

var src = document.getElementById("imgSrc").value;
var id = document.getElementById("preId").value;
var imgP = parent.document.getElementById(id);
imgP.src = src;
parent.setImgSrc(id,src);

这样就基本完成了,IE是一项能把人累死和逼疯的工做,漫漫长路,无穷无尽,真爱生命,远离IE浏览器。

相关文章
相关标签/搜索