ueditor多图上传至阿里云oss

今天做百度编辑器UEditor多图上传至阿里云oss,打开的弹框中有三个功能:插入图片本地上传图片搜索,其中插入图片功能正常,剩余两个需要自行完善

本地上传

本地图片上传有两个坑,分别是获取token,以及成功上传后的显示
由于我们需要上传到oss,需要自定义上传服务

相关代码如下

/**
 * 图片上传service
 * @param {Object} context UploadImage对象 图片上传上下文
 * @param {Object} editor  编辑器对象
 * @returns imageUploadService 对象
 */
window.UEDITOR_CONFIG['imageUploadService'] = function (context, editor) {
  return {
    /**
     * 触发fileQueued事件时执行
     * 当文件被加入队列以后触发,用来设置上传相关的数据 (比如: url和自定义参数)
     * @param {Object} file 当前选择的文件对象
     */
    setUploadData: function (file) {
      return file
    },
    /**
     * 触发uploadBeforeSend事件时执行
     * 在文件上传之前触发,用来添加附带参数
     * @param {Object} object 当前上传对象
     * @param {Object} data 默认的上传参数,可以扩展此对象来控制上传参数
     * @param {Object} headers 可以扩展此对象来控制上传头部
     * @returns 上传参数对象
     */
    setFormData: function (object, data, headers) {
      return data
    },
    /**
     * 触发startUpload事件时执行
     * 当开始上传流程时触发,用来设置Uploader配置项
     * @param {Object} uploader
     * @returns uploader
     */
    setUploaderOptions: function (uploader) {
      return uploader
    },
    /**
     * 触发uploadSuccess事件时执行
     * 当文件上传成功时触发
     * @param {Object} res 上传接口返回的response
     * @returns {Boolean} 上传接口返回的response成功状态条件 (比如: res.code == 200)
     */
    getResponseSuccess: function (res) {
      return res.code === 200
    },
    /* 指定上传接口返回的response中图片路径的字段,默认为 url */
    imageSrcField: 'url'
  }
}

我们修改的重点便在这个service中,改动如下:

  • 在setUploaderOptions中判断是否有token,没有则停止上传并获取token,拿到token后继续上传
setUploaderOptions: function (uploader) {
if (!uploader.ossInfo) {
  uploader.stop()
  // 获取oss图片上传 token
  that.$Post('/get-osstoken', {}).then(res => {
    if (res) {
      uploader.ossInfo = res
      uploader.upload()
    }
  })
}
return uploader
}
  • 在setFormData中设置oss上传接口所需要的data
setFormData: function (object, data, headers) {
    let ossInfo = context.uploader.ossInfo.data
    data.key = ossInfo.dir + '/' + randomString(10) + getSuffix(data.name)
    data.policy = ossInfo.policy
    data.OSSAccessKeyId = ossInfo.accessid
    data.success_action_status = 200
    data.signature = ossInfo.signature
    let imageList = context.imageList || []
    imageList.push({
      url: ossInfo.host + '/' + key
    })
    return data
}

上边的两个方法封装在utils中

 /**
 * 随机码 对指定的字符串中随机取参数位
 */
export const randomString = function (len) {
  len = len || 32
  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  var maxPos = chars.length
  var pwd = ''
  for (var i = 0; i < len; i++) {
    pwd += chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return pwd
}

/**
 * 获取文件后缀
 */
export const getSuffix = function (filename) {
  let pos = filename.lastIndexOf('.')
  let suffix = ''
  if (pos != -1) {
    suffix = filename.substring(pos)
  }
  return suffix
}

获取token的方法也单独封装


/**
 * 获取oss图片上传 token (进入相关页面预先请求)
 * @returns {Promise.<T>}
 */
import Vue from 'vue'
import { storageSet, storageGet } from './storage'
import { ossBaseDir } from './../config'

const expireTime = 3000 * 1000
export const getUploadToken = function (cb, ...param) {
  let nowTime = new Date().getTime()
  let uploadTokenExpireTime = storageGet('uploadTokenExpireTime')
  if (uploadTokenExpireTime && nowTime < uploadTokenExpireTime) {
    var ossInfo = storageGet('uploadTokenInfo')
    return cb(ossInfo, ...param)
  } else {
    Vue.Posting('/admin/user/get-osstoken', { dir: ossBaseDir }).then(res => {
      if (res) {
        let ossInfo = {
          OSSAccessKeyId: res.data.accessid,
          host: res.data.host,
          dir: res.data.dir,
          policy: res.data.policy,
          signature: res.data.signature,
          success_action_status: '200' // 让服务端返回200,不然,默认会返回204
        }
        storageSet('uploadTokenExpireTime', new Date().getTime() + expireTime) // 设置 token 过期时间
        storageSet('uploadTokenInfo', ossInfo)
        return cb(ossInfo, ...param)
      } else {
        // 当错误的时候,进行错误统一处理
        console.log(res)
      }
    }).catch(() => {})
  }
}

  • 在getResponseSuccess中设置上传成功的状态
getResponseSuccess: function (res) {
  return true
}

至此图片上传成功,接下来就是数据展示:

修改dialogs/image/image.js 760行 getInsertList() 函数

getInsertList: function () {
  var i, data, list = [],
    align = getAlign(),
    prefix = editor.getOpt('imageUrlPrefix'),
    imageSrcField = editor.getOpt("imageUploadService")(this, editor).imageSrcField || 'url';
  for (i = 0; i < this.imageList.length; i++) {
    data = this.imageList[i];
    // 去除无效的图片对象
    if(data[imageSrcField]) { // 添加这行
      list.push({
          src: prefix + data[imageSrcField],
          _src: prefix + data[imageSrcField],
          alt: data.original,
          floatStyle: align
      });
    }   // 添加这行
  }
  return list;
}

图片搜索

图片搜索可以正常搜到图片并展示,但是点击确认后在编辑器中未能正常显示

解决方法:修改neditor.all.js源码
找到25857行开始的下列源码注释

var src = ci.getAttribute("_src") || ci.src || "";
if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) {
  remoteImages.push(src);
  // 添加上传时的uploading动画
  domUtils.setAttributes(ci, {
    class: "loadingclass",
    _src: src,
    src: loadingIMG
  })
}

文章作者: 徐辉波
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 徐辉波 !
评论
 上一篇
阿里前端监控 阿里前端监控
为什么要有前端监控 随着前端项目的迭代更新,页面的代码逐渐增多,逻辑也越来越复杂,这时可能会遇到以下问题 如果用户访问我们的站点时遇到错误,我们无法在第一时间得知,还需要用户上报才能发现,而且上报也只能得到出现了错误,无法得知具体的
2018年10月12日
下一篇 
JS基础试题(一) JS基础试题(一)
1、分别用迭代和递归实现数组的扁平化 flatten flatten([1, 2, [3, [4, [5]]]]) // [1, 2, 3, 4, 5] 解析: // 迭代 const flatten = function (arr) {
2018年10月11日
  目录