ueditor 结合vue 上传图片,视频,附件到七牛云

ueditor上传七牛经历了一个多星期,终于做的比较满意的实现了,期间踩过很多坑,就不分享这些坑了,直接说最后的成品,当然这里面还是有很多bug没有修复。具体问题大家具体分析吧。我纪录下我的结果。
首先是参考文章列表如下:

1、UEditor1.4.3版本-直接上传视频、附件、图片到七牛云存储,并且支持图片在线管理功能:[https://github.com/widuu/qiniu_ueditor_1.4.3]

ueditor 结合vue 上传图片,视频,附件到七牛云_第1张图片
不过作者 php文件夹里面的config.json 这一句注释错误了,会导致errorHandler is not defined。各位需要注意。

2、Vue +UEditor + v-model双向绑定:[https://github.com/HaoChuan9421/vue-ueditor-wrap]
3、百度编辑器上传视频以及视频编辑器预览bug解决:[https://blog.csdn.net/belen_xue/article/details/73252802]

我写的项目是根据iview-admin改的后台,所以先根据 链接2在项目中引入ueditor的双向绑定,因为VueUeditorWrap 绑定的也是实际项目public目录下的ueditor所以在把链接1的文件下载下来,放入public目录。具体的就不说了直接上图
ueditor 结合vue 上传图片,视频,附件到七牛云_第2张图片
ueditor放的位置,iview-admin放的是public文件夹下,如果是vue-cli放的static文件夹下

ueditor 结合vue 上传图片,视频,附件到七牛云_第3张图片
这个时候富文本编辑器应该可以显示出来了,舞台搭好了,然后才是我们的大戏。

单图直接上传七牛

根据链接1的文章,更改好配置后,我们发现上传图片还是会报错。如果你认真对比了链接1链接2中的关于单图上传的代码你就会发现,2号作者也发现了这个问题。
ueditor 结合vue 上传图片,视频,附件到七牛云_第4张图片
由于ueditor使用的ueditor.all.min.js压缩以后不好更改,所以我的做法是直接用ueditor.all.js在线压缩,然后把压缩后的内容覆盖目前的ueditor.all.min.js内容,我的用的编辑器是vscode,使用beautify插件一键格式化ueditor.all.min.js然后找到simpleupload方法
如下代码替换原代码:

UE.plugin.register('simpleupload', function() {
    var me = this,
      containerBtn,
      timestrap = (+new Date()).toString(36);//时间转换为36进制的字符串
    function initUploadBtn() {
      var w = containerBtn.offsetWidth || 20,
        h = containerBtn.offsetHeight || 20,
        btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;';
  
      var form = document.createElement('form');
      var input = document.createElement('input');
      form.id = 'edui_form_' + timestrap;
      form.enctype = 'multipart/form-data';
      form.style = btnStyle;
      input.id = 'edui_input_' + timestrap;
      input.type = 'file'
      input.accept = 'image/*';
      input.name = me.options.imageFieldName;
      input.style = btnStyle;
      form.appendChild(input);
      containerBtn.appendChild(form);
      input.addEventListener('change', function(event) {
        if (!input.value) return;
        var loadingId = 'loading_' + (+new Date()).toString(36);
        var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName'));
        var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';
        var action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?' : '&') + params);
        var allowFiles = me.getOpt('imageAllowFiles');
        me.focus();
        me.execCommand('inserthtml', '');
        function showErrorLoader(title) {
          if (loadingId) {
            var loader = me.document.getElementById(loadingId);
            loader && domUtils.remove(loader);
            me.fireEvent('showmessage', {
              'id': loadingId,
              'content': title,
              'type': 'error',
              'timeout': 4000
            });
          }
        }
        /* 判断后端配置是否没有加载成功 */
        if (!me.getOpt('imageActionName')) {
          showErrorLoader(me.getLang('autoupload.errorLoadConfig'));
          return;
        }
        // 判断文件格式是否错误
        var filename = input.value,
          fileext = filename ? filename.substr(filename.lastIndexOf('.')) : '';
        if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {
          showErrorLoader(me.getLang('simpleupload.exceedTypeError'));
          return;
        }
        var xhr = new XMLHttpRequest()
        xhr.open('post', action, true)
        // console.log(action)
        if (me.options.headers && Object.prototype.toString.apply(me.options.headers) === "[object Object]") {
          for (var key in me.options.headers) {
            xhr.setRequestHeader(key, me.options.headers[key])
          }
        }
        // console.log(xhr.status)
        xhr.onload = function() {
          if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            var res = JSON.parse(xhr.responseText)
            var link = me.options.imageUrlPrefix + res.url;
            // console.log(res)
            if (res.state == 'SUCCESS' && res.url) {
              // console.log(res);
              loader = me.document.getElementById(loadingId);
              loader.setAttribute('src', link);
              loader.setAttribute('_src', link);
              loader.setAttribute('title', res.title || '');
              loader.setAttribute('alt', res.original || '');
              loader.removeAttribute('id');
              domUtils.removeClasses(loader, 'loadingclass');
              me.fireEvent("contentchange");
            } else {
              showErrorLoader(res.state);
            }
          } else {
            showErrorLoader(me.getLang('simpleupload.loadError'));
          }
        };
        xhr.onerror = function() {
          showErrorLoader(me.getLang('simpleupload.loadError'));
        };
        xhr.send(new FormData(form));
        form.reset();
      })
    }
  
    return {
      bindEvents: {
        'ready': function() {
          //设置loading的样式
          utils.cssRule('loading',
            '.loadingclass{display:inline-block;cursor:default;background: url(\'' +
            this.options.themePath +
            this.options.theme + '/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n' +
            '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' +
            this.options.themePath +
            this.options.theme + '/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' +
            '}',
            this.document);
        },
        /* 初始化简单上传按钮 */
        'simpleuploadbtnready': function(type, container) {
          containerBtn = container;
          me.afterConfigReady(initUploadBtn);
        }
      },
      outputRule: function(root) {
        utils.each(root.getNodesByTagName('img'), function(n) {
          if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) {
            n.parentNode.removeChild(n);
          }
        });
      }
    }
  });

相当于form表单上传的方式。
这个时候关于链接1中的上传配置也要做相应的修改: controller.php中修改如下
ueditor 结合vue 上传图片,视频,附件到七牛云_第5张图片
这个时候单图直接上传七牛的功能已经实现了,然后多图上传因为有很多bug,我就直接忽略了,不适用多图上传,其实问题很上传视频和附件的,然后小伙伴们还想使用,可以根据下面的内容自行修改。

上传视频到七牛

找到video.js我的文件目录如下
public\UEditor\dialogs\video\video.js
上传七牛首先要解决的是获取token的问题,链接1作者是自己写的生成token的办法,或者我的理解有错,我遇到的问题是token不匹配,所以我是调取后端接口生成的token。因为jsonp是可以跨域传数据,所以ajax同步的请求方式失效了
ueditor 结合vue 上传图片,视频,附件到七牛云_第6张图片
执行到这一步还是有问题的,文件虽然上传成功了,但是回显数据是有问题的,那我们继续往下看token是上传前需要获取的,这个时候我们上传成功了,但是还是会文件框还是会显示一个红条报错,那我们找一下是哪里的问题,因为ueditor是结合webuploader完成上传的,那么看uploadSuccess这个方法,通过在代码中的不同位置console.log()不同的内容来确定报错的位置。最后确定是try()方法中的if()判断出了问题,那为什么if判断为假呢,console.log(json)发现,json的返回中并没有if判断需要的数据,那自己添加拼接一个不就行了,代码如下:

 uploader.on('uploadSuccess', function (file,ret) {
                var $file = $('#' + file.id);
                try {
                    var json;
                    // 分片上传通过服务器合成来返回数据
                    if( isChunked ){
                        var url = editor.getActionUrl(editor.getOpt('makeFileActionName')),
                        isJsonp = utils.isCrossDomainUrl(url);
                        $.ajax({
                            dataType : isJsonp ? 'jsonp':'json',
                            async    : false,
                            method   : 'post',
                            data     : { ctx : qiniuCtx, type : file.type, size : file.size, name:file.name, host:chunkUploadUrl},
                            url      : url,
                            success:function(data) {
                                json = data;
                            }
                        });
                    }else{
                        var responseText = (ret._raw || ret);
                        json = utils.str2json(responseText);
                        json['state'] = 'SUCCESS';
                        json['url']= 'http://img.*******.com/'+ json.key;//这里需要写你自己七牛的存储空间的域名
                    }
                    // var responseText = (ret._raw || ret),
                    //     json = utils.str2json(responseText);
                    if (json.state == 'SUCCESS') {
                        uploadVideoList.push({
                            'url': json.url,
                            'type': json.type,
                            'original':json.original
                        });
                        $file.append('');
                    } else {
                        $file.find('.error').text(json.state).show();
                    }
                } catch (e) {
                    $file.find('.error').text(lang.errorServerUpload).show();
                }
            });

OK!到这里视频上传就完成了,关于视频预览无法加载的问题请参考链接3

附件上传七牛

解决办法如同视频上传七牛,小伙伴自行实践吧。vue小白一枚,如果有问题欢迎评论讨论!

你可能感兴趣的:(web前端)