环境:java,springmvc,ckeditor,tomcat,maven
情况:在做项目的时候发现本地图片粘贴到ckeditor中,img标签的src中的值是“data:image/png;base64,”开头的,后面会跟一串字符串,图片越大字符串越长,这样的图片在保存的时候一旦放多了过后,后台不知什么原因拿不到其它的参数,所以想把这种图片上传到后台在显示出来。研究了一天的发觉还是挺简单的,主要是ckeditor怎么获取img并获取src 。下面看一下代码。
流程:监听change事件-》获取图片的二进制数据,将base64图片转换成formData再提交到服务器-》服务器接收上传的文件,生成图片到指定位置,并返回图片的访问地址-》js接收回调数据,获得图片url-》将获得的url地址替换掉图片的二进制数据
1,定义一个textarea
<textarea id="content" name="content">${article.content}</textarea> <!--ckeditor编辑器 初始化设置 --> <script type="text/javascript"> CKEDITOR.replace('content', {extraPlugins : 'codesnippet',codeSnippet_theme : 'monokai_sublime',height : 520});</script>
2,js方法
//粘贴图片上传 //延时加载uploadImage方法,否则被默认方法覆盖 $(function(){setTimeout(uplaodImage,400);}); //使用FormData形式,将base64图片转换成formData再提交(图片不限制大小) function uplaodImage(){ CKEDITOR.instances.content.on('change',function(e){//content为textarea的id var a = e.editor.document ; var b = a.find("img"); var count = b.count(); for(var i=0;i<count;i++){ var src =b.getItem(i).$.src;//获取img的src if(src.substring(0,10)=='data:image'){ //判断是否是二进制图像,是才处理 var img1=src.split(',')[1]; var img2=window.atob(img1); alert('img2 size='+img2.length); var ia = new Uint8Array(img2.length); for (var x = 0; x < img2.length; x++) { ia[x] = img2.charCodeAt(x); }; //获得图片的类型 var w1=src.indexOf(":");//获得指定字符的第一个下标值 var w2=src.indexOf(";"); var imgType= src.substring(w1+1, w2);//返回一个包含从 start 到最后(不包含 end )的子字符串的字符串 var blob=new Blob([ia], {type:imgType}); var formdata=new FormData(); formdata.append('croppedImage',blob); $.ajax({ type:"POST", url:"${baseurl}article/uploadImage.action",//服务器url async:false,//同步,因为修改编辑器内容的时候会多次调用change方法,所以要同步,否则会多次调用后台 data:formdata, processData: false, contentType: false, success:function(json){ var imgurl=json.resultInfo.sysdata.url; //获取回传的图片url //alert('返回的url='+imgurl); //获取并更改到现有的图片标签src的值 b.getItem(i).$.src=imgurl; var a = CKEDITOR.instances.content.document.$.getElementsByTagName("img")[i]; //content为textarea的id a.setAttribute('data-cke-saved-src',imgurl); } }); } } }); }
3,后台方法
/** * ckeditor粘贴图片上传并返回访问路径(不限制图片大小) * @param imgfile 图片文件 * @return */ @RequestMapping(value = "uploadImage", method = RequestMethod.POST) public @ResponseBody SubmitResultInfo uploadImage(@RequestParam("croppedImage") MultipartFile imgfile) { try { //获取 文件后缀 String fileSuffixes =imgfile.getContentType().split("/")[1];// data:image/png // 生成文件名称 Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String filename = sdf.format(cal.getTime()); // 生成图片保存路径 String filePath = "E:/temp/tempfile" + "/" + filename + "." + fileSuffixes; // 图片访问路径 String fileurl = "http://localhost:5080/upimg/" + filename + "." + fileSuffixes; System.out.println("fileurl=" + fileurl); // 写文件到磁盘 File newFile = new File(filePath); imgfile.transferTo(newFile); //返回url ResultInfo resultInfo = ResultUtil.createSuccess(Config.MESSAGE, 906, null); resultInfo.getSysdata().put("url", fileurl);//返回的图片访问路径 return ResultUtil.createSubmitResult(resultInfo); } catch (Exception e) { e.printStackTrace(); return ResultUtil.createSubmitResult(ResultUtil.createSuccess(Config.MESSAGE, 911, null));//500错误 } }
4,其它环境配置
4.1在spinrg-mvc.xml中配置配置上传解析器
<!-- 配置上传解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="52428800" /><!-- 限制上传文件的大小 --> <property name="defaultEncoding" value="UTF-8" /> </bean>
4.2,pom.xml引入依赖
<!-- 上传文件依赖 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
4.3,配置图片的虚拟路径,如
部分参考:http://blog.csdn.net/modernzcl/article/details/18365151