zoukankan      html  css  js  c++  java
  • ueditor 的java实现粘贴微信文章时 反微信反盗链

    需求背景是这样的:

    微信的图片经过了反盗链的处理,所以直接在编辑器中粘贴,在浏览器中查看会出现一张“不得外链”的占位图,所以操作起来不太方便,还得一个一个重传,所以在编辑器层面处理一下,基本思路是这样的:

    1.拦截编辑器的粘贴事件

    2.找到粘贴的html中img标签

    3.把img标签图片下载并重新传到自己的服务器(这里是阿里云oss),返回链接

    4.把新链接替换掉原链接

    5.完成粘贴


    一。首先,本地ueditor开发环境部署

    这里参考了这个帖子:

    【UEditor】 UEditor整合项目上传资源到阿里云服务器


    以及

    利用ueditor的文件上传功能上传文件到外部服务器的地址&&&&&字符统计功能重写


    博客另给出了一个demo下载:http://download.csdn.net/detail/qq457557442/8322227

    十分感谢


    下载下来后,是maven的项目,编译运行没什么问题




    二。demo项目是将图片上传到自己的服务器,考虑到稳定等问题,这里还是放到阿里云oss


    找到代码:

    @RequestMapping(value="upload",method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
            @ResponseBody
            public Map<String,Object> upload(HttpServletRequest req){
                Map<String,Object> result = new HashMap<String, Object>();
    
                MultipartHttpServletRequest mReq  =  null;
                MultipartFile file = null;
                InputStream is = null ;
                String fileName = "";
                // 原始文件名   UEDITOR创建页面元素时的alt和title属性
                String originalFileName = "";
                String filePath = "";
    
                try {
                    mReq = (MultipartHttpServletRequest)req;
                    // 从config.json中取得上传文件的ID
                    file = mReq.getFile("upfile");
                    // 取得文件的原始文件名称
                    fileName = file.getOriginalFilename();
    
    
                    originalFileName = fileName;
    
                    if(!StringUtils.isEmpty(fileName)){
                        is = file.getInputStream();
                        fileName = FileUtils.reName(fileName);
                        filePath = FileUtils.saveFile(fileName, is, fileuploadPath);
                    } else {
                        throw new IOException("文件名为空!");
                    }
    
                    result.put("state", "SUCCESS");// UEDITOR的规则:不为SUCCESS则显示state的内容
                    result.put("url",httpPath + filePath);
                    result.put("title", originalFileName);
                    result.put("original", originalFileName);
                }
                catch (Exception e) {
                    System.out.println(e.getMessage());
                    result.put("state", "文件上传失败!");
                    result.put("url","");
                    result.put("title", "");
                    result.put("original", "");
                    System.out.println("文件 "+fileName+" 上传失败!");
                }
    
                return result;
            }


    file = mReq.getFile("upfile");
    词句后面,我们可以将file接入阿里云oss api,返回一个url,将url塞到result中,替换掉
    result.put("url",httpPath + filePath);
    ok,done,测试一下,ok


    另,demo中的代码仅跟踪了

            if (action == 'uploadimage' || action == 'uploadfile') {
                var id = $('#carInfoId').val();
              return '<%=contextPath %>/ueditor/fileupload/upload.do';
            } else {
                return this._bkGetActionUrl.call(this, action);
            }


    上传图片和上传文件两种情况,我这边再追加两种情况:

    uploadscrawl和uploadvideo

    前者是涂鸦板,后者是上传视频,参考:ueditor常见用法

    uploadimage//执行上传图片或截图的action名称

    uploadscrawl//执行上传涂鸦的action名称

    uploadvideo//执行上传视频的action名称

    uploadfile//controller,执行上传视频的action名称

    catchimage//执行抓取远程图片的action名称



    但是出于未知原因,uploadscrawl一直出问题,需求未指出,我这边也就搁置了

     RequestFacade cannot be cast to MultipartHttpServletRequest 文件上传转换出错



    三。拦截粘贴事件

    参考:

    百度编辑器UEditor,怎样禁止用户粘贴


    editor_a.addListener('beforepaste', myEditor_paste); 
            function myEditor_paste(o, html) {
                html.html = "";
                alert("只能录入不能粘贴");
           }


    四。将粘贴的html代码建立一个dom

    参考:js 字符串转dom 和dom 转字符串


    我这边,

    ue.addListener('beforepaste', myEditor_paste);
    function myEditor_paste(o, html) {
    //	html.html = "";
    //	alert("只能录入不能粘贴");
    //	console.log(html.html);
    
    	var objE = document.createElement("div");
    	objE.id = 'divparse';
    	objE.innerHTML = html.html;


    五。找到里面的img标签,下载图片,上传图片取得新链接,替换链接

    	var imgArr=objE.getElementsByTagName("img");
    	if(imgArr.length > 0) {
    
    		var r=confirm("检测到"+imgArr.length+"张外链图片,是否进行转换(来源为微信的建议转换)?")
    		if (r==true) {
    			alert("开始转换");
    			for(var i=0; i<imgArr.length; ++i) {
    				var url = imgArr[i].getAttribute("data-src")
    			//	console.log(url);
    				document.title = "正在转换第"+(i+1)+"张图片";
    
    				$.ajax( {
    					url:"ueditor/fileupload/uploadUrl.do",// 跳转到 action
    					data:{
    						url : url
    					},
    					type:'post',
    					cache:false,
    					dataType:'json',
    					async: false,
    					success:function(data) {
    						if(data.state == 1 ){
    						//	alert(data.url);
    							imgArr[i].removeAttribute("data-src");
    							imgArr[i].removeAttribute("src");
    							imgArr[i].removeAttribute("_src");
    							imgArr[i].setAttribute("src", data.url);
    						//	console.log(imgArr[i]);
    						//	document.title = "第"+(i+1)+"张图片转换成功";
    						}else{
    							alert("第"+(i+1)+"张图片转换失败,请自行单独上传");
    						}
    					},
    					error : function() {
    						// view("异常!");
    						alert("异常!");
    					}
    				});
    			}
    			alert("转换完毕");
    			document.title = "";
    			console.log(objE.innerHTML);
    			html.html = objE.innerHTML;
    		} else {
    			;
    		}
    	}

    url:"ueditor/fileupload/uploadUrl.do",// 跳转到 action

    此请求是后端请求,将原微信图片地址下载,然后上传阿里云oss,返回给前端url

    imgArr[i].removeAttribute("data-src");
    							imgArr[i].removeAttribute("src");
    							imgArr[i].removeAttribute("_src");
    							imgArr[i].setAttribute("src", data.url);

    这是去除原img标签的链接,设置为新的阿里云oss链接


    html.html = objE.innerHTML;

    最后,将dom的html链接再给ueditor,ok,看上去确实替换掉了


    六。这时,发生了一个问题,虽然innerHTML已经是将所有图片链接替换了,但是点击ueditor的html按钮查看源代码,外部粘贴的链接发现都是本地链接,经查,原来是ueditor默认打开抓取远程图片本地化功能,

    参考此帖: UEditor编辑器如何关闭抓取远程图片本地化功能

    场景:直接copy图片至ueditor的时候,编辑器会默认将图片本地化并返回本地化的src

    问题:日积月累本地化copy的图片对服务器压力很大

    需求:去掉copy图片本地化

    解决办法:

    1、打开ueditor.all.js

       搜索“抓取”的时候出现以下代码:

       

    [javascript] view plain copy
    1. // plugins/catchremoteimage.js  
    2. ///import core  
    3. ///commands 远程图片抓取  
    4. ///commandsName  catchRemoteImage,catchremoteimageenable  
    5. ///commandsTitle  远程图片抓取  
    6. /** 
    7.  * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片 
    8.  */  
    9. UE.plugins['catchremoteimage'] = function () {  
    10.     var me = this,  
    11.         ajax = UE.ajax;  
    12.     /* 设置默认值 */  
    13.     if (me.options.catchRemoteImageEnable === falsereturn;  
    14.     me.setOpt({  
    15.         catchRemoteImageEnable: false  
    16.     });  
    17.     //.......  
    18. };  

    发现:catchRemoteImageEnable

    2、打开ueditor.config.js

        在空白处添加

        

    [javascript] view plain copy
    1. //抓取远程图片是否开启,默认true  
    2. ,catchRemoteImageEnable:false  


    使用此方法,ok了,查看源代码也是阿里云oss链接(记得清除浏览器缓存)


    七。基础功能到这里已经完成了,接下去要加一个初始化查值-赋值的功能,

    查看此帖:百度编辑器ueditor初始化赋值

    1. var ue = UE.getEditor('editor');//初始化对象  
    2.     $(document).ready(function(){  
    3.         var ue = UE.getEditor('editor');  
    4.         var proinfo=$("#divdata").text();  
    5.           
    6.         ue.ready(function() {//编辑器初始化完成再赋值  
    7.             ue.setContent(proinfo);  //赋值给UEditor  
    8.         });  
    9.           
    10.     });  

    我这里:

    查:

    	$.ajax( {
    		url:reqUrl + section+"/getContent2/"+id,// 跳转到 action
    		data:{},
    		type:'get',
    		cache:false,
    		dataType:'json',
    		async: false,
    		success:function(data) {
    			console.log(data);
    			if(data.data == null)
    				data.data = "";
    
    			ue.setContent(data.data);
    		},
    		error : function(XMLHttpRequest, textStatus, errorThrown) {
    			;
    		}
    	});

    改:

    var save = function () {
    	var text = ue.getContent();
    	$.ajax( {
    		url:reqUrl + section +"/saveContent2/"+id,// 跳转到 action
    		data:{content2:text},
    		type:'post',
    		cache:false,
    		dataType:'json',
    		async: false,
    		success:function(data) {
    			console.log(data);
    			alert(data.msg);
    			location.reload()
    		},
    		error : function(XMLHttpRequest, textStatus, errorThrown) {
    			;
    		}
    	});
    }


    记得需要再ue.ready中setContent

    ok,整改功能已经完成。



    八。细心的读者应当已经发现第二点中,有一个

    catchimage//执行抓取远程图片的action名称

    这样一个事件,这个事件直接监控粘贴的远程图片,如果建立一个控制器来处理这个事件,那么是否也能完成功能?

    我这里就不再改实现了,以后有空了再实践


    最后给一个微信文章链接,一直用这个链接做测试

    https://mp.weixin.qq.com/s/UJBRPAZfFcPJaHKrENHlbw





    9.15 补充

    chrome上传图片(批量)时,反应很慢:


    使用谷歌浏览器(chrome)访问UEditor上传图片时文件选择框延迟弹出的解决方法

    http://blog.csdn.net/lhtzbj12/article/details/53673601   


    ueditor chrome中图片上传框延时问题

    http://blog.csdn.net/higuioiuujiu/article/details/53423479


    我这里只动了:

          
            modified:   src/main/webapp/ueditor/dialogs/image/image.js
            modified:   src/main/webapp/ueditor/ueditor.all.js
            modified:   src/main/webapp/ueditor/ueditor.all.min.js


    三个文件即完成了上传图片及批量上传图片的延迟问题



    再补充,原代码的编辑框没有滚动条,导致复制时没法自动下拉上拉


    https://zhidao.baidu.com/question/488123034071703212.html

    scaleEnabled {Boolean} [默认值:false] //是否可以拉伸长高,默认true(当开启时,自动长高失效)

    参考代码:
    var ue = UE.getEditor('container',{
    initialFrameWidth :800,//设置编辑器宽度
    initialFrameHeight:250,//设置编辑器高度
    scaleEnabled:true
    });






    11.16 补充:取消自动保存:

    https://tieba.baidu.com/p/3210789252?red_tag=2552847840

    ueditor.config.js 中

    saveInterval: (60*60*24)


    这个只是带过  本以为是自动保存缓存的问题,后来发现是后端的问题

  • 相关阅读:
    [mysql练习]多行结果合并问题练习
    【Python】Python多进程练习
    【mysql练习】转置,总计,分组
    【Mysql】HDFS文件上传流程
    [Jmeter][基础]Jmeter连接IMPALA
    【Linux】 -bash-4.2#问题和Cannot allocate memory
    微服务学习之路
    好的东西一定要收藏-持续更新
    Python日期的加减等操作
    NGINX动态增加模块,平滑升级
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106791.html
Copyright © 2011-2022 走看看