一開始用官方的上傳圖片的代碼javascript
ClassicEditor.create(document.querySelector('#editor'), { ckfinder: { uploadUrl:"" + rootPath + "/qiNiu/uploadFile.json" //圖片上傳url } } ).then(editor => { } ) .catch(error => { console.log(error); } );
後臺能夠收到圖片,並返回json數據。返回到前端會報錯,提示Cannot upload file:xxx.png html
直到今天看了CKEditor中ckfinder的源碼才發現問題。閱讀ckeditor5-adapter-ckfinder發現,ckfinder也定義了UploadAdapter,一樣實現了upload()和 abort() 方法。而問題就出如今upload()方法中。下面貼出upload()方法的源碼:前端
upload() { return new Promise( ( resolve, reject ) => { this._initRequest(); this._initListeners( resolve, reject ); this._sendRequest(); } ); } _initListeners( resolve, reject ) { const xhr = this.xhr; const loader = this.loader; const t = this.t; const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`; xhr.addEventListener( 'error', () => reject( genericError ) ); xhr.addEventListener( 'abort', () => reject() ); xhr.addEventListener( 'load', () => { const response = xhr.response; if ( !response || !response.uploaded ) { return reject( response && response.error && response.error.message ? response.error.message : genericError ); } resolve( { default: response.url } ); } ); // Upload progress when it's supported. /* istanbul ignore else */ if ( xhr.upload ) { xhr.upload.addEventListener( 'progress', evt => { if ( evt.lengthComputable ) { loader.uploadTotal = evt.total; loader.uploaded = evt.loaded; } } ); } }
從上面源碼中能夠發現,ckfinder請求以後的返回體response應該不爲空,且還要包括uploaded和url字段,因此返回數據實際格式應該是{"uploaded":1,"url":"/"},如此就不會出錯了。因此,返回的數據並非按照「教程「」說的那樣。java
upload.jspajax
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>上傳圖片測試</title> </head> <body> <div> <textarea name="content" id="editor"> <p>這裏寫內容</p> </textarea> </div> </body> <script type="text/javascript" src="${pageContext.request.contextPath}/ckeditor/ckeditor.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/javascript/editor_common.js"></script> </html>
editor_common.jsjson
ClassicEditor.create(document.querySelector('#detailContent'), {}) .then(editor => { editor.plugins.get('FileRepository').createUploadAdapter = (loader) => { return new UploadAdapter(loader); }; console.log('Editor was initialized'); }) .catch(error => { console.log(error) }); //自定義適配器 class UploadAdapter { constructor(loader) { this.loader = loader; } upload() { return new Promise((resolve, reject) => { const data = new FormData(); data.append('file', this.loader.file); data.append('allowSize', 10);//容許圖片上傳的大小/兆 $.ajax({ url: "" + rootPath + "/qiNiu/uploadFile.json",//上傳圖片的url type: 'POST', data: data, dataType: 'json', processData: false, contentType: false, success: function (data) { var tempObj = data.data; var status = data.success; if (status==true) { resolve({ default: tempObj.imageUrl }); } else { reject(data.msg); } } }); }); } abort() { } }
後臺Controllerapp
@Controller @RequestMapping("/test") public class TestController { @RequestMapping(value = "/demo") public String demo() { return "/ui/demo"; } }
上傳文件的Controllerjsp
@RestController @RequestMapping(value = "qiNiu") public class QiNiuUploadController { public String getUpToken() { String ACCESS_KEY = Constant.QINIU_ACCESS_KEY; String SECRET_KEY = Constant.QINIU_SECRET_KEY; String bucketname = Constant.QINIU_BUCKETNAME; Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); return auth.uploadToken(bucketname); } @RequestMapping(value = "/uploadFile") @ResponseBody public ResultSupport upload(@RequestParam("file") MultipartFile file) { ResultSupport resultSupport=new ResultSupport(); //構造一個帶指定Zone對象的配置類 Configuration cfg = new Configuration(Zone.zone0()); //...其餘參數參考類註釋 UploadManager uploadManager = new UploadManager(cfg); //...生成上傳憑證,而後準備上傳 //默認不指定key的狀況下,以文件內容的hash值做爲文件名 SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd"); String folderName=simpleDateFormat.format(new Date()); String key = folderName+"/"+System.currentTimeMillis()+file.getOriginalFilename(); try { StringMap stringMap=new StringMap(); Response response = uploadManager.put(file.getInputStream(), key, getUpToken(),stringMap,"image/jpeg"); //解析上傳成功的結果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); resultSupport.failSupport("上傳文件失敗",ResultCode.FAIL_YEWU); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { //ignore resultSupport.failSupport("上傳文件失敗",ResultCode.FAIL_YEWU); } } catch (IOException e) { e.printStackTrace(); resultSupport.failSupport("上傳文件失敗",ResultCode.FAIL_YEWU); } Map<String,Object> map=new HashMap<>(); map.put("imageUrl",Constant.ROOT_QINIU+key); map.put("fileName",key); return resultSupport.successQuery("上傳文件成功",map); } }
參考:測試
https://www.jianshu.com/p/47e25447b771ui