百度的开源前端富文本编辑器Ueditor各种有着强大的功能,但是在实际项目中,往往不会把图片直接上传到后端服务器上,而是上传到图床或者CDN上,那么如何配置呢?
其中controller.php 是一个控制器文件,里面做了一个简单的路由,可以看到有一个uploadimage 路由到了action_upload.php
switch ($action) {
case 'config':
$result = json_encode($CONFIG);
break;
/* 上传图片 */
case 'uploadimage':
/* 上传涂鸦 */
case 'uploadscrawl':
/* 上传视频 */
case 'uploadvideo':
/* 上传文件 */
case 'uploadfile':
$result = include("action_upload.php");
break;
/* 列出图片 */
case 'listimage':
$result = include("action_list.php");
break;
/* 列出文件 */
case 'listfile':
$result = include("action_list.php");
break;
/* 抓取远程文件 */
case 'catchimage':
$result = include("action_crawler.php");
break;
default:
$result = json_encode(array(
'state'=> '请求地址出错'
));
break;
}
action_upload.php则实例化了Uploader.class.php的Uploader类,其中做的主要操作就是文件的移动操作
//创建目录失败
if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
$this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
return;
} else if (!is_writeable($dirname)) {
$this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
return;
}
//移动文件
if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) { //移动失败
$this->stateInfo = $this->getStateInfo("ERROR_FILE_MOVE");
} else { //移动成功
$this->stateInfo = $this->stateMap[0];
}
所以通过分析这个过程,我们可以看到,ueditor是在前端上传图片时调用了/controller.php?action=uploadimage这个接口,而我们要做的就是将移动文件操作修改为上传到远程图床或者CDN。
在ueditor.all.js中有一个方法getActionUrl返回了不同操作对应的接口地址
/**
* 根据action名称获取请求的路径
* @method getActionUrl
* @remind 假如没有设置serverUrl,会根据imageUrl设置默认的controller路径
* @param { String } action action名称
* @example
* ```javascript
* editor.getActionUrl('config'); //返回 "/ueditor/php/controller.php?action=config"
* editor.getActionUrl('image'); //返回 "/ueditor/php/controller.php?action=uplaodimage"
* editor.getActionUrl('scrawl'); //返回 "/ueditor/php/controller.php?action=uplaodscrawl"
* editor.getActionUrl('imageManager'); //返回 "/ueditor/php/controller.php?action=listimage"
* ```
*/
getActionUrl: function(action){
var actionName = this.getOpt(action) || action,
imageUrl = this.getOpt('imageUrl'),
serverUrl = this.getOpt('serverUrl');
if(!serverUrl && imageUrl) {
serverUrl = imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2');
}
if(serverUrl) {
serverUrl = serverUrl + (serverUrl.indexOf('?') == -1 ? '?':'&') + 'action=' + (actionName || '');
return utils.formatUrl(serverUrl);
} else {
return '';
}
}
那么我们只要在页面中重写这个方法,让它返回我们自己的上传图片接口地址就可以了
在编辑的页面中加入以下代码,其中当action等于uploadimage时调用我们自己的上传接口,否则走原有的ueditor的接口
UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
UE.Editor.prototype.getActionUrl = function(action) {
if (action == 'uploadimage') {
return '/mycontroller/uploadimage';
} else {
return this._bkGetActionUrl.call(this, action);
}
}
同时在初始化Ueditor时将远程抓取图片的功能关闭,否则会在复制粘贴时自动讲一个CDN上的图片抓取保存到本地服务器
var ue = UE.getEditor('container',{
initialFrameHeight : 600,
initialFrameWidth : 1500,
catchRemoteImageEnable:false,
})
后端的PHP接口读取上传文件内容,然后调用图床或者CDN提供的上传接口就可以了,注意这里接口返回的数据格式应与Ueditor接口返回的相同,否则会报错
$file = $_FILES['upfile'];
if ($_FILES["file"]["error"] == 0) {
//上传文件到CDN
$res = array(
"state" => "", //上传状态,上传成功时必须返回"SUCCESS"
"url" => "", //CDN地址
"title" => "", //新文件名
"original" => "", //原始文件名
"type" => "", //文件类型
"size" => "", //文件大小
);
echo json_encode($res);
}
这样当使用Ueditor的上传图片功能时,就会把图片上传到图床或者CDN了。