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,在上述兩個文件的訪問路徑配置上增加版本號文件路徑。