什么是UEditor
UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户
体验优秀等特点。开源基于BSD协议,所有源代码在协议允许范围内可自由修改和使用。百度UEditor
的推出,可以帮助不少网站开发者在开发富文本编辑器所遇到的难题,节约开发者因开发富文本编辑器
所需要的大量时间,有效降低了企业的开发成本。
官网:官网
教程文档地址:教程文档
API文档地址:api
为什么使用UEditor?
用于替换textarea,textarea是纯文本编辑器,样式比较简陋。使用富文本编辑器,样式丰富,所见即所得。
UEditor本质上是一个html。
使用-demo
- 加载两个js
- 加载编辑器的容器(文本编辑器默认值)
- 实例化编辑器
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>ueditor demo</title>
</head>
<body>
<!-- 加载编辑器的容器 -->
<script id="container" name="content" type="text/plain">javascript">
这里写你的初始化内容
</script>
<!-- 配置文件 -->
<script type="text/javascript" src="ueditor.config.js"></script>
<!-- 编辑器源码文件 -->
<script type="text/javascript" src="ueditor.all.js"></script>
<!-- 实例化编辑器 -->
<script type="text/javascript">
var ue = UE.getEditor('container');
</script>
</body>
</html>
UEditor 和 转义
使用UEditor必须要转义,这是为什么?
为了安全起见,防止数据库操作失败。
安全起见:必须转义,防止恶意脚本被执行。当标签传递给浏览器的时候,浏览器把他们解析为标签,就会被执行。在一个富文本编辑器中,当用户输入一个<script>
标签时,如果这个标签不被转义,那么浏览器就会将它解析为一个脚本标签,并且执行其中的 JavaScript 代码。这种情况下,如果攻击者能够注入恶意脚本,那么页面就有可能被攻击者控制。当标签被转义后,当需要被解析的时候,会和普通文本一样呈现在页面中,不会被浏览器解析执行。如果想要动态效果可以通过js代码,如jquery,react,vue等。
防止数据库操作失败,如双引号或者单引号如果没有被转义可能会造成sql注入的问题。
public void testHtml(){
String html = HtmlUtils.htmlEscape("<p><span>测试html文本转义与反转义<span>
<p>","UTF-8");
System.out.println(html);
System.out.println(HtmlUtils.htmlUnescape(html));
}
应用
三大步骤
1、引入配置文件
2、提供容器,将插件放入容器中
3、加载容器,调用工具函数
前端:
引入配置文件
<!-- 百度 ueditor -->
<script type="text/javascript" charset="utf-8" src="${ctx}/plugins/Ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="${ctx}/plugins/Ueditor/ueditor.all.js"></script>
<script type="text/javascript" charset="utf-8" src="${ctx}/plugins/Ueditor/lang/zh-***/zh-***.js"></script>
提供容器,将插件放入容器中
提供一个文本域,将富文本编辑器放到文本域中。
<tr>
<td>商品详情描述:</td>
<td width="85%">
<textarea rows="6" cols="80" class="span12 ckeditor" id="goods_content"
name="goodsContent" title=""></textarea>
<span id="err_goods_content" style="color:#F00; display:none;"></span>
</td>
</tr>
加载容器,调用工具函数
<!--以下是在线编辑器 代码 -->
<script type="text/javascript">
/*
* 在线编辑器相 关配置 js
* 参考 地址 http://fex.baidu.***/ueditor/
*/
window.UEDITOR_Admin_URL = "${ctx}/plugins/Ueditor/";
var URL_upload = "/index/Admin/Ueditor/imageUp/savepath/goods";
var URL_fileUp = "/index/Admin/Ueditor/fileUp/savepath/article";
var URL_scrawlUp = "/index/Admin/Ueditor/scrawlUp/savepath/article";
var URL_getRemoteImage = "/index/Admin/Ueditor/getRemoteImage/savepath/article";
var URL_imageManager = "/index/Admin/Ueditor/imageManager/savepath/article";
var URL_imageUp = "/index/Admin/Ueditor/imageUp/savepath/article";
var URL_getMovie = "/index/Admin/Ueditor/getMovie/savepath/article";
var URL_home = "";
</script>
<script type="text/javascript">
var editor;
$(function () {
//具体参数配置在 editor_config.js 中
var options = {
zIndex: 999,
initialFrameWidth: "95%", //初化宽度
initialFrameHeight: 400, //初化高度
focus: false, //初始化时,是否让编辑器获得焦点true或false
maximumWords: 99999,
removeFormatAttributes:'class,style,lang,width,height,align,hspace,valign', //允许的最大字符数 'fullscreen',
pasteplain: false, //是否默认为纯文本粘贴。false为不使用纯文本粘贴,true为使用纯文本粘贴
autoHeightEnabled: true
/* autotypeset: {
mergeEmptyline: true, //合并空行
removeClass: true, //去掉冗余的class
removeEmptyline: false, //去掉空行
textAlign: "left", //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版
imageBlockLine: 'center', //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版
pasteFilter: false, //根据规则过滤没事粘贴进来的内容
clearFontSize: false, //去掉所有的内嵌字号,使用编辑器默认的字号
clearFontFamily: false, //去掉所有的内嵌字体,使用编辑器默认的字体
removeEmptyNode: false, //去掉空节点
//可以去掉的标签
removeTagNames: {"font": 1},
indent: false, // 行首缩进
indentValue: '0em' //行首缩进的大小
}*/,
toolbars: [
['fullscreen', 'source', '|', 'undo', 'redo',
'|', 'bold', 'italic', 'underline', 'fontborder',
'strikethrough', 'superscript', 'subscript',
'removeformat', 'formatmatch', 'autotypeset',
'blockquote', 'pasteplain', '|', 'forecolor',
'backcolor', 'insertorderedlist',
'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize',
'|', 'directionalityltr', 'directionalityrtl',
'indent', '|', 'justifyleft', 'justifycenter',
'justifyright', 'justifyjustify', '|', 'touppercase',
'tolowercase', '|', 'link', 'unlink', 'anchor', '|',
'imagenone', 'imageleft', 'imageright', 'imagecenter',
'|', 'insertimage', 'emotion', 'insertvideo',
'attachment', 'map', 'gmap', 'insertframe',
'insertcode', 'webapp', 'pagebreak', 'template',
'background', '|', 'horizontal', 'date', 'time',
'spechars', 'wordimage', '|',
'inserttable', 'deletetable',
'insertparagraphbeforetable', 'insertrow', 'deleterow',
'insertcol', 'deletecol', 'mergecells', 'mergeright',
'mergedown', 'splittocells', 'splittorows',
'splittocols', '|', 'print', 'preview', 'searchreplace']
]
};
editor = new UE.ui.Editor(options);
editor.render("goods_content"); // 指定 textarea 的 id 为 goods_content,将文本编辑器的内容放到文本框中
});
</script>
<!--以上是在线编辑器 代码 end-->
后端:
前端页面写好商品描述详情之后,点击保存按钮,发送异步请求到Controller中。对接收过来的goods的商品详情描述内容进行转义。
Controller
@RequestMapping("/save")
@ResponseBody
public BaseResult goodsSave(Goods goods){
BaseResult error = BaseResult.error();
//如果商品详情不为空,则转义UEditor文本编辑器
if(!StringUtils.isEmpty(goods.getGoodsContent())){
String s = HtmlUtils.htmlEscape(goods.getGoodsContent(), "utf-8");
goods.setGoodsContent(s);
}
System.out.println("保存商品");
if(goods.getGoodsId()!=null){
error.setMessage("重复保存!保存失败!");
return error;
}
int result = goodsService.saveGoods(goods);
System.out.println("商品id"+goods.getGoodsId());
if(result>0){
BaseResult su***ess = BaseResult.su***ess();
su***ess.setMessage(String.valueOf(goods.getGoodsId()));
return su***ess;
}
error.setMessage("系统繁忙,请联系管理员!");
return error;
}