ueditor远程图片本地化的实现
前不久客户反馈说,在秀米网上编辑好文章,发布到我们后台,前台图片无法显示,最先想到的是图片域名限制。发邮件给秀米,秀米给出的建议是类似微信后台做图片本地化。
开发组内部讨论后,看到了这篇文章,UEditor编辑器如何关闭抓取远程图片本地化功能,so easy?按文章说明设置,测试,失败!
百度看了下,大都是这样解答,说明应该是有人实现了,秀米编辑器核心代码也正是ueditor核心代码,那就只能自己捣鼓了。
具体捣鼓过程如下:
注意:捣鼓前先备份下,以备修改错误导致其他问题
打开ueditor.config.js,在配置项中加入
,catchRemoteImageEnable:true
打开ueditor.config.js,搜索catchremoteimage,在加入console.warn(url),看看上传地址。前台测试后看到/Skin/public/ueditor/php/controller.php?action=catchimage
打开php/controller.php 可以看到
case 'catchimage': $result = include("action_crawler.php"); break;
接着打开统计目录下action_crawler.php
include("Uploader.class.php"); $item = new Uploader($imgUrl, $config, "remote");
看到这两段代码。继续打开统计目录下Uploader.class.php
//构造函数如下 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']); }
搜索saveRemote,主要修复fileType与oriName两块。
/** * 拉取远程图片 * @return mixed */ 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, '.'));
//puresai 20170712 秀米网链接接如下http://img.xiumi.us/xmi/ua/h4qG/i/b8f2af6986e8dba51615a9d85cc82f3b-sz_1952250.JPG?x-oss-process=style/xm ,我们完善下
$fileType = (strpos($fileType, '?') > 0)? strtolower(substr($fileType,0,strpos($fileType,'?'))) : strtolower($fileType);
//echo $fileType;die();
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 // don't follow redirects
))
);
readfile($imgUrl, false, $context);
$img = ob_get_contents();
ob_end_clean();
//puresai 20170712 此处正则有问题,修改如下
//preg_match("//[.]?[^./]*$/", $imgUrl, $m);
preg_match("//[A-za-z0-9-]+.".$fileType."/", strtolower($imgUrl), $m);
//var_dump($m);die();$this->oriName = $m ? ltrim($m[0],'/'):"";
//$this->oriName = $m ? $m[1]:"";
//echo $this->oriName;
//die();
$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;
}//创建目录失败
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 (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
$this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
} else { //移动成功
$this->stateInfo = $this->stateMap[0];
}}
打开php/config.json,修改大小、格式、存储路径等参数
/ 抓取远程图片配置 / "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"], "catcherActionName": "catchimage", / 执行抓取远程图片的action名称 / "catcherFieldName": "source", / 提交的图片列表表单名称 / "catcherPathFormat": "/Upload/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}", / 上传保存路径,可以自定义保存路径和文件名格式 / "catcherUrlPrefix": "", / 图片访问路径前缀 / "catcherMaxSize": 20480000, / 上传大小限制,单位B / "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], / 抓取图片格式显示 /
5.保存修改上传,测试成功!