zoukankan      html  css  js  c++  java
  • 在linux下使用百度ueditor编辑器上传图片

    百度ueditor编辑器虽然强大,但是也有不足的地方。如果对ueditor流程不是很熟悉可以说走的弯路比较多,费力不讨好。下面呢,就是要解决ueditor遇到的问题。

    用ueditor上传图片遇到的问题是服务器错误

    虽然上传成功但是服务器返回出错,对于没有经验或者是初学者都回去百度搜,结果不是很理想。而且越走越偏。

    第一步:修改路径文件config.json

    /* 前后端通信相关的配置,注释只允许使用多行方式 */
    {
        /* 上传图片配置项 */
        "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
        "imageFieldName": "upfile", /* 提交的图片表单名称 */
        "imageMaxSize": 4096000, /* 上传大小限制,单位B */
        "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
        "imageCompressEnable": true, /* 是否压缩图片,默认是true */
        "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
        "imageInsertAlign": "none", /* 插入的图片浮动方式 */
        "imageUrlPrefix": "", /* 图片访问路径前缀 */
        "imagePathFormat": "/public/ueditor/php/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                    /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                    /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                    /* {time} 会替换成时间戳 */
                                    /* {yyyy} 会替换成四位年份 */
                                    /* {yy} 会替换成两位年份 */
                                    /* {mm} 会替换成两位月份 */
                                    /* {dd} 会替换成两位日期 */
                                    /* {hh} 会替换成两位小时 */
                                    /* {ii} 会替换成两位分钟 */
                                    /* {ss} 会替换成两位秒 */
                                    /* 非法字符 \ : * ? " < > | */
                                    /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
    
        /* 涂鸦图片上传配置项 */
        "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
        "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
        "scrawlPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
        "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
        "scrawlInsertAlign": "none",
    
        /* 截图工具上传 */
        "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
        "snapscreenPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
        "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
    
        /* 抓取远程图片配置 */
        "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
        "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
        "catcherFieldName": "source", /* 提交的图片列表表单名称 */
        "catcherPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "catcherUrlPrefix": "", /* 图片访问路径前缀 */
        "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
        "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
    
        /* 上传视频配置 */
        "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
        "videoFieldName": "upfile", /* 提交的视频表单名称 */
        "videoPathFormat": "/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "videoUrlPrefix": "", /* 视频访问路径前缀 */
        "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
        "videoAllowFiles": [
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
    
        /* 上传文件配置 */
        "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
        "fileFieldName": "upfile", /* 提交的文件表单名称 */
        "filePathFormat": "/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "fileUrlPrefix": "", /* 文件访问路径前缀 */
        "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
        "fileAllowFiles": [
            ".png", ".jpg", ".jpeg", ".gif", ".bmp",
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
            ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
            ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
        ], /* 上传文件格式显示 */
    
        /* 列出指定目录下的图片 */
        "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
        "imageManagerListPath": "/ueditor/php/upload/image/", /* 指定要列出图片的目录 */
        "imageManagerListSize": 20, /* 每次列出文件数量 */
        "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
        "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
        "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
    
        /* 列出指定目录下的文件 */
        "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
        "fileManagerListPath": "/ueditor/php/upload/file/", /* 指定要列出文件的目录 */
        "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
        "fileManagerListSize": 20, /* 每次列出文件数量 */
        "fileManagerAllowFiles": [
            ".png", ".jpg", ".jpeg", ".gif", ".bmp",
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
            ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
            ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
        ] /* 列出的文件类型 */
    
    }
    

      我们发现虽然改了随意路径(/public/ueditor/php/image/)上传大小可以根据自己的需求修改。但是还会服务器返回出错,而且this request has no preview available(没有任何请求)。

    第二步:打开controller.php文件

     1 <?php
     2 //header('Access-Control-Allow-Origin: http://www.baidu.com'); //设置http://www.baidu.com允许跨域访问
     3 //header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With'); //设置允许的跨域header
     4 date_default_timezone_set("PRC");
     5 error_reporting(E_ERROR);
     6 header("Content-Type: text/html; charset=utf-8");
     7 $CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents("config.json")), true);
     8 $action = $_GET['action'];
     9 switch ($action) {
    10     case 'config':
    11         $result =  json_encode($CONFIG);
    12         break;
    13 
    14     /* 上传图片 */
    15     case 'uploadimage':
    16     /* 上传涂鸦 */
    17     case 'uploadscrawl':
    18     /* 上传视频 */
    19     case 'uploadvideo':
    20     /* 上传文件 */
    21     case 'uploadfile':
    22         $result = include("action_upload.php");
    23         break;
    24 
    25     /* 列出图片 */
    26     case 'listimage':
    27         $result = include("action_list.php");
    28         break;
    29     /* 列出文件 */
    30     case 'listfile':
    31         $result = include("action_list.php");
    32         break;
    33 
    34     /* 抓取远程文件 */
    35     case 'catchimage':
    36         $result = include("action_crawler.php");
    37         break;
    38 
    39     default:
    40         $result = json_encode(array(
    41             'state'=> '请求地址出错'
    42         ));
    43         break;
    44 }
    45 
    46 /* 输出结果 */
    47 if (isset($_GET["callback"])) {
    48     if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
    49         echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
    50     } else {
    51         echo json_encode(array(
    52             'state'=> 'callback参数不合法'
    53         ));
    54     }
    55 } else {
    56     echo $result;
    57 }菜鸟在调试controller.php经常忽略date_default_timezone_set("PRC");禁止显示错误。
    我们发现error_reporting(E_ERROR);关于ueditor资料遇到上传不成功都会说路径,而不会说controller.php文件下:error_reporting(E_ERROR)。可以修改成error_reporting(E_ALL)可以看到

    报错位置是Uploader.class.php on line 248。
    第三步:打开Uploader.class.php  
    <?php
    
    /**
     * Created by JetBrains PhpStorm.
     * User: taoqili
     * Date: 12-7-18
     * Time: 上午11: 32
     * UEditor编辑器通用上传类
     */
    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", //上传成功标记,在UEditor中内不可改变,否则flash判断会出错
            "文件大小超出 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"
        );
    
        /**
         * 构造函数
         * @param string $fileField 表单名称
         * @param array $config 配置项
         * @param bool $base64 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名
         */
        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']);
        }
    
        /**
         * 上传文件的主处理方法
         * @return mixed
         */
        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;
            }
    
            $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;
            }
    
            //创建目录失败
            if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
                //$this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
                $this->stateInfo = $dirname;
                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];
            }
        }
    
        /**
         * 处理base64编码的图片上传
         * @return mixed
         */
        private function upBase64()
        {
            $base64Data = $_POST[$this->fileField];
            $img = base64_decode($base64Data);
    
            $this->oriName = $this->config['oriName'];
            $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");
                $this->stateInfo = $dirname;
                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];
            }
    
        }
    
        /**
         * 拉取远程图片
         * @return mixed
         */
        private function saveRemote()
        {
            $imgUrl = htmlspecialchars($this->fileField);
            $imgUrl = str_replace("&amp;", "&", $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 // don't follow redirects
                ))
            );
            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;
            }
    
            //创建目录失败
            if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
                //$this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
            this->stateInfo = $dirname;
                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];
            }
    
        }
    
        /**
         * 上传错误检查
         * @param $errCode
         * @return string
         */
        private function getStateInfo($errCode)
        {
            return !$this->stateMap[$errCode] ? $this->stateMap["ERROR_UNKNOWN"] : $this->stateMap[$errCode];
        }
    
        /**
         * 获取文件扩展名
         * @return string
         */
        private function getFileExt()
        {
            return strtolower(strrchr($this->oriName, '.'));
        }
    
        /**
         * 重命名文件
         * @return string
         */
        private function getFullName()
        {
            //替换日期事件
            $t = time();
            $d = explode('-', date("Y-y-m-d-H-i-s"));
            $format = $this->config["pathFormat"];
            $format = str_replace("{yyyy}", $d[0], $format);
            $format = str_replace("{yy}", $d[1], $format);
            $format = str_replace("{mm}", $d[2], $format);
            $format = str_replace("{dd}", $d[3], $format);
            $format = str_replace("{hh}", $d[4], $format);
            $format = str_replace("{ii}", $d[5], $format);
            $format = str_replace("{ss}", $d[6], $format);
            $format = str_replace("{time}", $t, $format);
    
            //过滤文件名的非法自负,并替换文件名
            $oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));
            $oriName = preg_replace("/[\|\?\"\<\>\/\*\\\\]+/", '', $oriName);
            $format = str_replace("{filename}", $oriName, $format);
    
            //替换随机字符串
            $randNum = rand(1, 10000000000) . rand(1, 10000000000);
            if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
                $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
            }
    
            $ext = $this->getFileExt();
            return $format . $ext;
        }
    
        /**
         * 获取文件名
         * @return string
         */
        private function getFileName () {
            return substr($this->filePath, strrpos($this->filePath, '/') + 1);
        }
    
        /**
         * 获取文件完整路径
         * @return string
         */
        private function getFilePath()
        {
            $fullname = $this->fullName;
            $rootPath = $_SERVER['DOCUMENT_ROOT'];
    
            if (substr($fullname, 0, 1) != '/') {
                $fullname = '/' . $fullname;
            }
    
            return $rootPath . $fullname;
        }
    
        /**
         * 文件类型检测
         * @return bool
         */
        private function checkType()
        {
            return in_array($this->getFileExt(), $this->config["allowFiles"]);
        }
    
        /**
         * 文件大小检测
         * @return bool
         */
        private function  checkSize()
        {
            return $this->fileSize <= ($this->config["maxSize"]);
        }
    
        /**
         * 获取当前上传成功文件的各项信息
         * @return array
         */
        public function getFileInfo()
        {
            return array(
                "state" => $this->stateInfo,
                "url" => $this->fullName,
                "title" => $this->fileName,
                "original" => $this->oriName,
                "type" => $this->fileType,
                "size" => $this->fileSize
            );
        }
    
    }

    发现248行由于误删,导致报错。那我们就修改248行代码。修改完成后再次刷新/ueditor/php/controller.php?action=uploadimage&encode=utf-8页面。

    刷新页面完成又报/ueditor/php/Uploader.class.php on line 66 不管它。我们再次开启error_reporting(E_ERROR);

    我们试一次看看是否成功

    成功了(备注:在linux系统下修改路径要注意权限)。

  • 相关阅读:
    element 树形控件使用
    js粘贴图片并显示
    vue-element Tree树形控件通过id默认选中
    解决win10shift+右键显示在此处打开powershell而不是命令窗口的问题
    maven安装与配置
    解决dos窗口中文乱码问题
    vue单页面应用刷新网页后vuex的state数据丢失的解决方案
    vue 单个倒计时组件
    js将秒转换为时分秒
    vue3.0用vue-awesome-swiper
  • 原文地址:https://www.cnblogs.com/liuyu2014/p/6624359.html
Copyright © 2011-2022 走看看