Vue - Vue + Spring Boot集成UEditor(含图片上传)
Vue + Spring Boot集成UEditor(含图片上传)
最近的vue项目中用到了UEditor,想着上网搜一搜demo就可以解决问题。但UEditor官网的最后一次版本更新是 1.4.3.3,这已经是 2016 年的事情了。踩了很多坑终于完成了这个功能,遂写一篇文章记录一下。
添加依赖
下载UEditor和vue-ueditor-wrap:
链接: https://pan.baidu.com/s/1EYZLWmRE516zvtNi7c8c2Q
提取码: 5bvh
之所以不用 npm i vue-ueditor-wrap 安装依赖,是因为之后会有修改源码的需求。
在这里感谢 https://github.com/HaoChuan9421/vue-ueditor-wrap,
本文的很多灵感来自于这里。
按照下图所示将文件夹放到项目中
引入到页面
引入组件:
import VueUeditorWrap from '../../../../static/plugins/vue-ueditor-wrap'
注册组件:
components: {VueUeditorWrap},
自定义工具栏:
myConfig: { toolbars: [ [ ] ], // 编辑器不自动被内容撑高 autoHeightEnabled: false, // 初始容器高度 initialFrameHeight: 700, // 初始容器宽度 initialFrameWidth: '100%', // 上传文件接口 serverUrl: 你的图片上传路径, },
由于项目涉密,这里只能贴上脱敏后的代码,可能会有报错,但大概结构可以看到
<template> <div v-loading="editorLoading"> <el-form :inline="true"> <vue-ueditor-wrap v-model="detail" :isClear="isClear" @change="change" :config="myConfig"></vue-ueditor-wrap> </el-form> </div> </template> <script> import VueUeditorWrap from '../../../../static/plugins/vue-ueditor-wrap' export default { components: {VueUeditorWrap}, data() { return { isClear: false, editorLoading: false, detail: "", myConfig: { toolbars: [ [ 'undo', //撤销 'forecolor', //字体颜色 'backcolor', //背景色 'bold', //加粗 'italic', //斜体 'underline', //下划线 'strikethrough', //删除线 'fontborder', //字符边框 'subscript', //下标 'superscript', //上标 'simpleupload', //单图上传 'insertimage', //多图上传 ] ], // 编辑器不自动被内容撑高 autoHeightEnabled: false, // 初始容器高度 initialFrameHeight: 700, // 初始容器宽度 initialFrameWidth: '100%', // 上传文件接口 serverUrl: 你的图片上传路径, }, } }, methods: { change(val) { this.detail = val; }, //提交文档 submit() { if (!this.detail) { alert('请输入内容'); return false; } this.editorLoading = true; this.$http.post(this.$http.adornUrl(`富文本编辑器内容保存路径`), { 'content': this.detail, }).then(result => { if (result.data && result.data.code === 0) { this.$message({ message: "操作成功", type: "success", duration: 1500, onClose: () => { this.detail = ''; } }); this.editorLoading = false; } else { this.$message.error(""); this.editorLoading = false; } }) } } } </script>
后台代码支持
上述文件中的
serverUrl
非常重要,富文本编辑器无论是获取配置文件信息还是上传图片都需要调用这个路径,只是请求方法和参数不一样,我这里后台用的是Spring Boot。
添加配置文件类UEditorConfig:
public class UEditorConfig { public final static String UEDITOR_CONFIG = "{\n" + " \"imageActionName\": \"uploadimage\",\n" + " \"imageFieldName\": \"upfile\",\n" + " \"imageMaxSize\": 2048000,\n" + " \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" + " \"imageCompressEnable\": true,\n" + " \"imageCompressBorder\": 1600,\n" + " \"imageInsertAlign\": \"none\",\n" + " \"imageUrlPrefix\": \"\",\n" + " \"imagePathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + "\n" + " \"scrawlActionName\": \"uploadscrawl\",\n" + " \"scrawlFieldName\": \"upfile\",\n" + " \"scrawlPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + " \"scrawlMaxSize\": 2048000,\n" + " \"scrawlUrlPrefix\": \"\",\n" + " \"scrawlInsertAlign\": \"none\",\n" + "\n" + " \"snapscreenActionName\": \"uploadimage\",\n" + " \"snapscreenPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + " \"snapscreenUrlPrefix\": \"\",\n" + " \"snapscreenInsertAlign\": \"none\",\n" + "\n" + " \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" + " \"catcherActionName\": \"catchimage\",\n" + " \"catcherFieldName\": \"source\",\n" + " \"catcherPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + " \"catcherUrlPrefix\": \"\",\n" + " \"catcherMaxSize\": 2048000,\n" + " \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" + "\n" + " \"videoActionName\": \"uploadvideo\",\n" + " \"videoFieldName\": \"upfile\",\n" + " \"videoPathFormat\": \"/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + " \"videoUrlPrefix\": \"\",\n" + " \"videoMaxSize\": 102400000,\n" + " \"videoAllowFiles\": [\n" + " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" + " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"],\n" + "\n" + " \"fileActionName\": \"uploadfile\",\n" + " \"fileFieldName\": \"upfile\",\n" + " \"filePathFormat\": \"/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + " \"fileUrlPrefix\": \"\",\n" + " \"fileMaxSize\": 51200000,\n" + " \"fileAllowFiles\": [\n" + " \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" + " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" + " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" + " \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" + " \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" + " ],\n" + "\n" + " \"imageManagerActionName\": \"listimage\",\n" + " \"imageManagerListPath\": \"/ueditor/jsp/upload/image/\",\n" + " \"imageManagerListSize\": 20,\n" + " \"imageManagerUrlPrefix\": \"\",\n" + " \"imageManagerInsertAlign\": \"none\",\n" + " \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" + "\n" + " \"fileManagerActionName\": \"listfile\",\n" + " \"fileManagerListPath\": \"/ueditor/jsp/upload/file/\",\n" + " \"fileManagerUrlPrefix\": \"\",\n" + " \"fileManagerListSize\": 20,\n" + " \"fileManagerAllowFiles\": [\n" + " \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" + " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" + " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" + " \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" + " \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" + " ] \n" + "\n" + "}"; /** * Ueditor的返回状态类型 */ public enum UeditorMsg { SUCCESS("SUCCESS"), ERROR("上传失败"); private String v; UeditorMsg(String v) { this.v = v; } public String get() { return this.v; } } }
添加controller返回配置。要获得传入参数的callback字段,然后根据特殊格式返回配置参数:
/** * 获取ueditor参数 */ @GetMapping("/ueditor-config") public String ueditorGet(@RequestParam Map<String, Object> params) { String callback = (String) params.get("callback"); return callback + "(" + UEditorConfig.UEDITOR_CONFIG + ")"; }
以上两个配置是必须的,否则点击上传图片工具时,会显示“后端配置项没有正常加载”:
添加图片上传接口。这里上传时的参数 upfile 是特定的字段名,返回参数state也必须是等于SUCCESS时,UEditor插件才能触发下一步操作。返回的url需要能够外网访问,这一部分功能我会在之后的文章中写出。
/** * ueditor上传图片 */ @PostMapping("/ueditor-config") public Map<String, String> ueditorPost(@RequestParam Map<String, Object> params, @RequestParam("upfile") MultipartFile file) { String name = (String) params.get("name"); String type = (String) params.get("type"); String size = (String) params.get("size"); String fileName = ""; if (!file.isEmpty()) { //返回的是字节长度,1M=1024k=1048576字节 也就是if(fileSize<5*1048576) if (file.getSize() > (1048576 * 5)) { logger.error("文件大小不能超过5M"); } //判断文件是否有后缀 String suffix = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf(".")); if (StringUtils.isBlank(suffix)) { logger.error("上传文件没有后缀,无法识别"); } //重命名文件以防文件名冲突 fileName = System.currentTimeMillis() + file.getOriginalFilename(); //判断文件夹是否存在,不存在则新建 File folder = new File(你的文件保存路径); if (!folder.exists()) { folder.mkdirs(); } try { file.transferTo(new File(folder, fileName)); //保存文件 } catch (Exception e) { logger.error("上传失败", e); } } else { logger.error("上传失败"); } Map<String, String> map = new HashMap<>(); map.put("state", "SUCCESS"); map.put("url", 你对外开放的文件访问端口 + fileName); map.put("title", name); map.put("original", ""); map.put("type", type); map.put("size", size); return map; }
之后需要修改nginx配置文件nginx.conf。
server { listen 你开放的端口; #监听端口(如8084) server_name localhost; #设置域名 location / { root 你的文件保存路径; #上传图片目录(如/Users/helios_fz/Desktop/upload/ccec_image/) } }
到这里UEditor的引入和图片上传功能就集成完毕了。
Q&A:
1.增加默认字体
增加默认字体需要修改ueditor.config.js、zh-cn.js、en.js三个文件,在fontfamily处添加需要的字体类型即可:
2.上传图片存在跨域问题
修改image.js,在发送上传图片请求之前,给请求加上请求头:
header["Access-Control-Allow-Headers"] = "X-Requested-With"; header["Access-Control-Allow-Methods"] = "PUT,POST,GET,DELETE,OPTIONS"; header["Access-Control-Allow-Credentials"] = "true";
3.项目发布到生产环境之后,UEditor不显示,控制台报错:/static/UEditor 404
因为vue在打包发布到生产环境的时候,结构如下图所示。由图可见如果想要访问static文件夹内的资源,需要多访问一层vue版本文件夹。
UEditor想要从外网访问ueditor.config.js和ueditor.all.min.js组件时,因为访问路径没有兼容版本文件夹,所以会报404错误。
修改源码static/plugins/vue-ueditor-wrap/lib/vue-ueditor-wrap.min.js,在上述两个文件的访问路径配置上增加版本号文件路径。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步