1.集成前提条件:
1. 需要集成百度编辑器到环境中
2.https环境下才可以导出数据到百度编辑器,如果不是https环境,会出现错误
然后我们开始讲解如何集成:
2.引入资源:
//百度编辑器需要修改的文件(配置与原始的配置不一样,后面会详细讲)
<script type="text/javascript" src="/static/lib/ueditor1_4_3_3-utf8-php/utf8-php-xiumi/ueditor.config.js?t=1"></script>
<script type="text/javascript" src="/static/lib/ueditor1_4_3_3-utf8-php/utf8-php-xiumi/ueditor.all.min.js"></script>
//秀米编辑器的JS,这个需要下载(下载可以去xiumi.us下载,也可以参考博主提供的相关代码)
<script type="text/javascript" src="/static/lib/ueditor1_4_3_3-utf8-php/utf8-php-xiumi/xiumi-ue-dialog-v5.js"></script>
3.初始化百度编辑器:
<script>
var ue = UE.getEditor('editor');
</script>
//xiumi-ue-dialog-v5.js可以去官网下载,也可以直接使用博主提供的相关代码
UE.registerUI('dialog', function (editor, uiName) {
var btn = new UE.ui.Button({
name : 'xiumi-connect',
title : '秀米',
onclick: function () {
var dialog = new UE.ui.Dialog({
iframeUrl: '相对地址/XIUMI connect.html',//这个参数中的html需要下载或者使用博主提供的代码(后面会贴出代码)
editor : editor,
name : 'xiumi-connect',//打开页面指定名字
title : "秀米编辑器",//打开页面指定标题
cssRules : "width: " + (window.innerWidth - 60) + "px;" + "height: " + (window.innerHeight - 60) + "px;",//打开页面大小配置
});
dialog.render();
dialog.open();
}
});
return btn;
});
//XIUMI connect.html可以去官网下载,也可以直接使用博主提供的相关代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>XIUMI connect</title>
<style>
html, body {padding: 0;margin: 0;}
#xiumi {position: absolute;width: 100%;height: 100%;border: none;box-sizing: border-box;}
</style>
</head>
<body>
<!--引入秀米页面-->
<iframe id="xiumi" src="//xiumi.us/studio/v5#/paper"></iframe>
<!--引入秀米页面-->
<script type="text/javascript" src="./internal.js"></script>
<script>
var xiumi = document.getElementById('xiumi');
var xiumi_url = window.location.protocol + "//xiumi.us";
xiumi.onload = function () {xiumi.contentWindow.postMessage('ready', xiumi_url);};
document.addEventListener("mousewheel", function (event) {event.preventDefault();event.stopPropagation();});
window.addEventListener('message', function (event) {
if (event.origin == xiumi_url) {
editor.execCommand('insertHtml', event.data);
editor.fireEvent("catchRemoteImage");//这个配置一定写,catchRemoteImage表示自定义上传方法名(注意:秀米编辑器导入百度编辑器的时候,图片文件不会自动上传到我们自己设置服务器,所以这一点一定要写上)
dialog.close();
}
}, false);
</script>
</body>
</html>
4.ueditor.config.js配置修改:
//开启配置(去掉注释),开启这个配置的作用:秀米编辑器数据导入百度编辑器图片样式会错乱,所以需要配置:iframeCssUrl: URL + '/themes/iframe.css'
//开启配置(去掉注释),开启这个配置的作用:设置是否抓取远程图片(Ctrl+c和Ctrl+v会触发远程获取图片并上传到自己服务器事件):catchRemoteImageEnable: true
//修改配置:section[] 修改为 section:['class', 'style'],(作用是过滤器:秀米编辑器导入百度编辑器的过程中,class和style不被过滤,各种样式得以保存)
section:['class', 'style'],
//iframe.css:添加自己自定义样式(存放相对地址:ueditor/themes/iframe.css),这个需要自己重写,代码参考博主提供的demo
img {
max-width: 100%;
}
body {
overflow-y: scroll !important;
}
.view {
word-break: break-all;
}
.vote_area {
display: block;
}
.vote_iframe {
background-color: transparent;
border: 0 none;
height: 100%;
}
#edui1_imagescale{display:none !important;}
//上传到自己服务器的上传方法(PHP版),主要由两个文件(存储地址:ueditor/php):Uploader.class.php 和 config.json
//先讲Uploader.class.php文件(主要是引入OSS上传方法,集成OSS方法就不赘述了,可以参考阿里云)
<?php
//阿里云OSS上传自动加载文件(注意相对地址)
require_once realpath(dirname(__FILE__).'/../../../../../applicaction/libraries/aliyun-oss/autoload.php');
use OSS\OssClient;
use OSS\Core\OssException;
class Uploader
{
private $fileField; //文件域名
private $file; //文件上传对象
private $base64; //文件上传对象
private $config; //配置信息
private $oriName; //原始文件名
private $fileName; //新文件名
private $fullName; //完整文件名,即从当前配置目录开始的URL
private $filePath; //完整文件名,即从当前配置目录开始的URL
private $fileSize; //文件大小
private $fileType; //文件类型
private $stateInfo; //上传状态信息,
private $stateMap = array( //上传状态映射表,国际化用户需考虑此处数据的国际化
"SUCCESS",
"文件大小超出 upload_max_filesize 限制",
"文件大小超出 MAX_FILE_SIZE 限制",
"文件未被完整上传",
"没有文件被上传",
"上传文件为空",
"ERROR_TMP_FILE" => "临时文件错误",
"ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
"ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
"ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
"ERROR_CREATE_DIR" => "目录创建失败",
"ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
"ERROR_FILE_MOVE" => "文件保存时出错",
"ERROR_FILE_NOT_FOUND" => "找不到上传文件",
"ERROR_WRITE_CONTENT" => "写入文件内容错误",
"ERROR_UNKNOWN" => "未知错误",
"ERROR_DEAD_LINK" => "链接不可用",
"ERROR_HTTP_LINK" => "链接不是http链接",
"ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确",
"INVALID_URL" => "非法 URL",
"INVALID_IP" => "非法 IP"
);
/**
* 构造函数
*/
public function __construct($fileField, $config, $type = "upload")
{
$this->fileField = $fileField;
$this->config = $config;
$this->type = $type;
if ($type == "remote") {
$this->saveRemote();
} else if($type == "base64") {
$this->upBase64();
} else {
$this->upFile();
}
$this->stateMap['ERROR_TYPE_NOT_ALLOWED'] = iconv('unicode', 'utf-8', $this->stateMap['ERROR_TYPE_NOT_ALLOWED']);
//The AccessKeyId from OSS or STS
$this->accessKeyId="";
//The AccessKeySecret from OSS or STS
$this->accessKeySecret="";
//The domain name of the datacenter,For example: oss-cn-hangzhou.aliyuncs.com
$this->endpoint="";
}
/**
* 上传文件的主处理方法(这个需要替换原有的方法)
*/
private function upFile()
{
$file = $this->file = $_FILES[$this->fileField];
if (!$file) {
$this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");
return;
}
if ($this->file['error']) {
$this->stateInfo = $this->getStateInfo($file['error']);
return;
} else if (!file_exists($file['tmp_name'])) {
$this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
return;
} else if (!is_uploaded_file($file['tmp_name'])) {
$this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");
return;
}
//修改:上传阿里云OSS(file:表示存储地址)
$ossClient=new OssClient($this->accessKeyId,$this->accessKeySecret,$this->endpoint);
$ossClient->uploadFile('ine', 'file/'.date ('Ym') .'/'.$file['name'], $file['tmp_name']);
$this->oriName = $file['name'];
$this->fileSize = $file['size'];
$this->fileType = $this->getFileExt();
$this->fullName = $this->getFullName();
$this->filePath = $this->getFilePath();
$this->fileName = $this->getFileName();
$dirname = dirname($this->filePath);
//检查文件大小是否超出限制
if (!$this->checkSize()) {
$this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
return;
}
//检查是否不允许的文件格式
if (!$this->checkType()) {
$this->stateInfo = $this->getStateInfo("ERROR_TYPE_NOT_ALLOWED");
return;
}
$this->stateInfo = $this->stateMap[0];
}
/**
* 拉取远程图片(这个需要替换原有的方法)
*/
private function saveRemote()
{
$imgUrl = htmlspecialchars($this->fileField);
$imgUrl = str_replace("&", "&", $imgUrl);
//http开头验证
if (strpos($imgUrl, "http") !== 0) {
$this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
return;
}
preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
$host_with_protocol = count($matches) > 1 ? $matches[1] : '';
// 判断是否是合法 url
if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
$this->stateInfo = $this->getStateInfo("INVALID_URL");
return;
}
preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
$host_without_protocol = count($matches) > 1 ? $matches[1] : '';
// 此时提取出来的可能是 ip 也有可能是域名,先获取 ip
$ip = gethostbyname($host_without_protocol);
// 判断是否是私有 ip
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
$this->stateInfo = $this->getStateInfo("INVALID_IP");
return;
}
//获取请求头并检测死链
$heads = get_headers($imgUrl, 1);
if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
$this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
return;
}
//格式验证(扩展名验证和Content-Type验证)
$fileType = strtolower(strrchr($imgUrl, '.'));
if (!in_array($fileType, $this->config['allowFiles']) || !isset($heads['Content-Type']) || !stristr($heads['Content-Type'], "image")) {
$this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
return;
}
//打开输出缓冲区并获取远程图片
ob_start();
$context = stream_context_create(
array('http' => array('follow_location' => false))
);
readfile($imgUrl, false, $context);
$img = ob_get_contents();
ob_end_clean();
preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
$this->oriName = $m ? $m[1]:"";
$this->fileSize = strlen($img);
$this->fileType = $this->getFileExt();
$this->fullName = $this->getFullName();
$this->filePath = $this->getFilePath();
$this->fileName = $this->getFileName();
$dirname = dirname($this->filePath);
//检查文件大小是否超出限制
if (!$this->checkSize()) {
$this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
return;
}
$this->stateInfo = $this->stateMap[0];
}
/**
* 获取文件完整路径(这个需要替换原有的方法)
*/
private function getFilePath()
{
$fullname = $this->fullName;
return $fullname;
}
}
5.config.json配置修改:
/* 上传图片配置项 */
"imageActionName": "uploadimage", /* 执行上传图片的action名称 */
"imageFieldName": "upfile", /* 提交的图片表单名称 */
"imageMaxSize": 2048000, /* 上传大小限制,单位B */
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
"imageCompressEnable": true, /* 是否压缩图片,默认是true */
"imageCompressBorder": 1600, /* 图片压缩最长边限制 */
"imageInsertAlign": "none", /* 插入的图片浮动方式 */
"imageUrlPrefix": "https://oss-cn-shanghai.aliyuncs.com", /* 这个需要自己替换 */
"imagePathFormat": "/file/{yyyy}{mm}/{filename}", /* 上传保存路径*/
"catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
"catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
"catcherFieldName": "source", /* 提交的图片列表表单名称 */
"catcherPathFormat": "/file/{yyyy}{mm}/{filename}", /* 上传保存路径 */
"catcherUrlPrefix": "https://oss-cn-shanghai.aliyuncs.com", /* 这个需要自己替换 */
"catcherMaxSize": 2048000, /* 上传大小限制,单位B */
"catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
到此为止,前面所提的集成问题和图片上传问题就解决完成了
秀米编辑器(xiumi)+百度编辑器(Ueditor) 集成 已经完成:
秀米编辑器导出到百度编辑器格式问题,图片保存到自己的服务器(阿里云OSS)
示例截图