• oss、huawei、亚马逊、monio文件上传方法封装


    import request from 'utils/request';
    import config from 'config/Config'
    
    /**
     * 文件上传
     * @param {*} url 获取签名url
     * @param {*} file 上传文件
     * @param {*} callback 回调函数
     * @param {*} otherParams 其他参数
     * @param {*} type 上传类型 oss s3 huawei aws
     */
    let uploadFn = (url = '', file = {}, callback, otherParams = {}, type = 'oss') => {
      url += `?fileType=${file.type}`;
      // bucketKey 云配置的桶,相当于命名空间 
      config.bucketKey && (url += `&&bucketKey=${config.bucketKey}`);
      let params = {
        ossType: getUploadType(type),
        url
      }
      getSgin(params).then(res => {
        if (`${res.resultCode}` === '0') {
          let fnMap = {
            huawei: huaweiUpload,
            s3: s3Upload,
            aws: awsUpload,
            oss: ossUpload,
          }
          fnMap[type](file, callback, otherParams, res.data)
        }
      })
    }
    
    // 获取上传类型
    let getUploadType = (type) => {
      let typeEnum = {
        s3: 'MINIO',
        oss: 'ALIYUNOSS',
        huawei: 'HUAWEIOBS',
        aws: 'AMAZONS3'
      }
      return typeEnum[type]
    }
    
    // minio文件上传
    let s3Upload = (file, callback, otherParams = {}, data = {}) => {
      let formData = new FormData();
      let key = calculate_object_name(data.key, 'home', file.name, false);
      Object.keys(data).forEach(item => {
        if (item === 'key' || item === 'form-action') return;
        formData.append(item, data[item]);
      })
      formData.append('key', `${key}${file.name}`);
      formData.append('file', file);
      beginUpload(data['form-action'], formData, otherParams, callback, file, `${key}${file.name}`);
    }
    
    
    // 亚马逊文件上传
    let awsUpload = (file, callback, otherParams = {}, data = {}) => {
      let formData = new FormData();
      let key = calculate_object_name(data.key, 'home', file.name, false);
      Object.keys(data).forEach(item => {
        if (item === 'key' || item === 'form-action') return;
        formData.append(item, data[item]);
      })
      formData.append('key', `${key}${file.name}`);
      formData.append('file', file);
      beginUpload(data['form-action'], formData, otherParams, callback, file, `${key}${file.name}`);
    }
    
    // 华为文件上传
    let huaweiUpload = (file, callback, otherParams = {}, data = {}) => {
      let formData = new FormData();
      let key = calculate_object_name(data.key, 'home', file.name, false);
      formData.append('x-obs-acl', data['x-obs-acl']);
      formData.append('content-type', file.type);
      formData.append('policy', data.policy);
      formData.append('key', key);
      formData.append('AccessKeyId', data.AccessKeyId);
      formData.append('signature', data.signature);
      formData.append('file', file);
      beginUpload(data['form-action'], formData, otherParams, callback, file, key);
    }
    
    // oss文件上传
    let ossUpload = (file, callback, otherParams = {}, ossData = {}) => {
      let formData = new FormData();
      let ossKey = calculate_object_name(ossData.dir, 'home', file.name, false);
      formData.append('OSSAccessKeyId', ossData.accessid);
      formData.append('policy', ossData.policy);
      formData.append('signature', ossData.signature);
      formData.append('key', ossKey);
      formData.append('success_action_status', 200);
      formData.append('expire', ossData.expire);
      formData.append('file', file);
      beginUpload(ossData.host, formData, otherParams, callback, file, ossKey);
    }
    
    /**
     * 开始上传和成功后返回函数
     * @param {*} host 请求路径
     * @param {*} formData 数据
     * @param {*} otherParams 需要返回的参数
     * @param {*} callback 回调函数
     * @param {*} file 原文件
     * @param {*} key 上传文件名
     */
    let beginUpload = (host, formData, otherParams, callback, file = {}, key) => {
      uploadInterface({
        url: host,
        formData
      }).then(result => {
        // 在axios.interceptors.response中做请求失败返回,以便确定请求失败,成功是不会有返回值的
        if (result) return;
        // 解决出现两个//
        host[host.length - 1] === '/' && (host = host.slice(0, -1));
        otherParams._result = `${host}/${key}`;
        otherParams.file = file;
        typeof callback === 'function' && callback(otherParams);
        console.log(`${host}/${key}`, 'result', otherParams)
        return otherParams;
      })
    }
    
    // 获取签名
    let getSgin = (params = {}) => {
      return request({
        url: params.url,
        method: 'GET',
        headers: {
          ossType: params.ossType
        }
      })
    }
    
    // 上传文件
    let uploadInterface = (params = {}) => {
      return request({
        url: params.url,
        method: 'POST',
        data: params.formData,
        headers: {
          "Context-Type": 'multipart/form-data '
        }
      })
    }
    
    let fileSuffix = (filename) => {
      const splitFile = filename.split('.')
      const len = splitFile.length
      return '.' + splitFile[len - 1]
    }
    let random = (n = 32) => {
      var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
      var letter = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'
      var maxPos = chars.length
      var result = ''
      for (var i = 0; i < n; i++) {
        result += chars.charAt(Math.floor(Math.random() * maxPos))
      }
      result = letter.charAt(Math.floor(Math.random() * letter.length)) + result
      return result.substring(0, result.length - 1)
    }
    // 混淆上传文件的名字
    let calculate_object_name = (g_dirname, group, filename, isReal) => {
      if (!filename) {
        return ''
      }
      var suffix = fileSuffix(filename)
      var g_object_name = g_dirname + random(15) + suffix
      if (!!group && g_dirname) {
        if (g_dirname.indexOf('/') == -1) {
          g_dirname += '/'
        }
        g_object_name = decodeURIComponent(g_dirname + group + '/' + random(14) + suffix)
      }
      return g_object_name
    }
    
    export default uploadFn;

    亚马逊完整参数

    // 除了文件,其他数据由后端获取签名接口获取
    x-amz-date: 20210309T080505Z
    x-amz-signature: 'signature'
    acl: 'acl'
    x-amz-algorithm: 'x-amz-algorithm'
    Content-Type: image/jpeg
    x-amz-credential: 'x-amz-credential'
    policy:  'policy'
    key: '混淆文件名'
    file: (binary)

    minio完整参数

    // 和亚马逊参数基本差不多
    x-amz-date: 20210309T081113Z
    x-amz-signature: 'x-amz-signature'
    acl: 'acl'
    x-amz-algorithm: AWS4-HMAC-SHA256
    Content-Type: image/jpeg
    x-amz-credential: 'x-amz-credential'
    policy:  'policy'
    key: '混淆文件名'
    file: (binary)

    需要注意的一个点

    当配置了xhr.withCredentials = true时,必须在后端增加 response 头信息Access-Control-Allow-Origin,且必须指定域名,而不能指定为*。会造成上传文件地址如oss跨域。

    如果在同域下配置xhr.withCredentials,无论配置true还是false,效果都会相同,且会一直提供凭据信息(cookie、HTTP认证及客户端SSL证明等)

      

    如果你需要上传base64的图片,比如截图所得到的图片就是base64的图片,可以将base64图片转化为file图片,再进行上传,转换方法如下

    /**
     * base64图片转成file图片
     * @param {*} dataurl base64图片完整路径
     * @param {*} filename 即将命名的文件名
     */
    static base64ToFile = (dataurl, filename) => {
      var arr = dataurl.split(','),
        // 获取文件类型,如image/png
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, { type: mime });
    }
  • 相关阅读:
    cereal:C++实现的开源序列化库
    随笔
    我们一起成长
    青岛近代历史和文化资料整理
    Codeforces Round #580 (Div. 2)-D. Shortest Cycle(思维建图+dfs找最小环)
    CodeForces
    PAT甲级1151(由前序和中序确定LCA)
    记录使用vs code两天的心得
    AcWing 285. 没有上司的舞会(树形dp入门)
    POJ-3255-Roadblocks(次短路的另一种求法)
  • 原文地址:https://www.cnblogs.com/kewenxin/p/14506325.html
Copyright © 2020-2023  润新知