一开始用官方的上传图片的代码
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
直到今天看了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":"/"},如此就不会出错了。所以,返回的数据并不是按照“教程“”说的那样。
upload.jsp
<%@ 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.js
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() {
}
}
后台Controller
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/demo")
public String demo() {
return "/ui/demo";
}
}
上传文件的Controller
@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/47e25447b771