1. 程式人生 > >阿里oss 實現檔案上傳(前端程式碼)

阿里oss 實現檔案上傳(前端程式碼)

1.本人專案使用jquery寫的,而阿里雲oss程式碼是原生js所以有些地方會兩者共用。
2.這裡只展示前端的程式碼部分,整個流程是由後臺生成簽名–>前端點選上傳檔案的時候獲取到後臺返回的accessid、host、policy、signaturecom等引數–>請求成功並獲取到返回引數後前端將這些引數重新賦值(祥見程式碼),賦值成功後oss的puload元件會自動提交到後臺返回的host引數內的連結地址。–>此時檔案提交就成功了
3.本次專案使用的是阿里雲oss的服務端簽名直傳並設定回撥。
在這裡插入圖片描述
4.下載客戶端原始碼
在這裡插入圖片描述
5.因為本人專案用的jquery所以就直接在專案中引用了原始碼,如果是vue或者其他框架的話也可以npm進行安裝plupload,我這裡是直接script標籤引入檔案包
在這裡插入圖片描述


在這裡插入圖片描述

6.接下來就是在原始碼內根據需求進行更改開發

accessid = ''
accesskey = ''
host = ''
policyBase64 = ''
signature = ''
filename = ''
key = ''
expire = new Date().getTime() + 1000 * 60 * 30//設定簽名過期時間,如果是後臺設定該引數,則前端可以忽略不設定。
g_object_name = ''
g_object_name_type = ''
now = timestamp = Date.parse(new Date()) / 1000;


function send_request(opt) {//ajax封裝,原始碼內使用的是原生xmlhttp進行的請求,為了專案方便進行了重新封裝。
  opt = opt || {};
  opt.method = (opt.method || 'GET').toUpperCase();
  opt.url = opt.url || '';
  opt.async = opt.async || true;
  opt.data = opt.data || null;
  opt.success = opt.success || function () {
  };
  var xmlHttp = null;
  if (XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest();
  }
  else {
    xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
  }
  var params = [];
  for (var key in opt.data) {
    params.push(key + '=' + opt.data[key]);
  }
  var postData = params.join('&');
  if (opt.method.toUpperCase() === 'POST') {
    xmlHttp.open(opt.method, opt.url, opt.async);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
    xmlHttp.send(postData);
  }
  else if (opt.method.toUpperCase() === 'GET') {
    xmlHttp.open(opt.method, opt.url + '?' + postData, opt.async);
    xmlHttp.send(null);
  }
  xmlHttp.onreadystatechange = function () {
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
      opt.success(xmlHttp.responseText);
    }
  };
}

function get_signature() {//這裡是對簽名時間進行判斷,如果簽名過期時間是後臺設定則暫且不需要考慮這一塊
  // 可以判斷當前expire是否超過了當前時間, 如果超過了當前時間, 就重新取一下,3s 作為緩衝。
  now = timestamp = Date.parse(new Date()) / 1000;
  if (expire < now + 3) {
    body = send_request()
    var obj = eval("(" + body + ")");
    host = obj['host']
    policyBase64 = obj['policy']
    accessid = obj['accessid']
    signature = obj['signature']
    expire = parseInt(obj['expire'])
    // callbackbody = obj['callback']
    key = obj['dir']
    return true;
  }
  return false;
};

function random_string(len) {//隨機字串
  len = len || 32;
  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
  var maxPos = chars.length;
  var pwd = '';
  for (i = 0; i < len; i++) {
    pwd += chars.charAt(Math.floor(Math.random() * maxPos));
  }
  return pwd;
}

function get_suffix(filename) {
  pos = filename.lastIndexOf('.')
  suffix = ''
  if (pos != -1) {
    suffix = filename.substring(pos)
  }
  return suffix;
}

function calculate_object_name(filename) {//把隨機好的字串拼接在上傳檔名後面生成新的檔名進行儲存
  suffix = get_suffix(filename)
  g_object_name = key + random_string(10) + suffix
  console.log(g_object_name)
  return ''
}

function set_upload_param(up, filename, ret) {//設定阿里雲提交檔案所需的引數
  if (ret == false) {
    ret = get_signature()
  }
  g_object_name = key;
  if (filename != '') {
    suffix = get_suffix(filename)
    calculate_object_name(filename)

  }
  new_multipart_params = {//設定阿里雲進行檔案提交儲存時的引數
    'key': g_object_name,
    'policy': policyBase64,
    'OSSAccessKeyId': accessid,
    'success_action_status': '200', //讓服務端返回200,不然,預設會返回204
    // 'callback': callbackbody,
    'signature': signature,
  };

  up.setOption({
    'url': host,
    'multipart_params': new_multipart_params
  });

  up.start();
}

var uploader = new plupload.Uploader({//阿里oss plupload上傳元件
  runtimes: 'html5,flash,silverlight,html4',
  browse_button: 'selectfiles',
  //multi_selection: false,
  container: document.getElementById('container'),
  flash_swf_url: 'lib/plupload-2.1.2/js/Moxie.swf',
  silverlight_xap_url: 'lib/plupload-2.1.2/js/Moxie.xap',
  url: 'http://oss.aliyuncs.com',
  filters: {
    mime_types: [ //只允許上傳圖片和zip檔案
      {title: "Image files", extensions: "jpg,gif,png,bmp"},
      {title: "Zip files", extensions: "zip,rar"},
      {title: "Apk files", extensions: "apk"}
    ],
    max_file_size: '100mb', //最大隻能上傳10mb的檔案
    prevent_duplicates: true //不允許選取重複檔案
  },

  init: {
    PostInit: function () {
      document.getElementById('ossfile').innerHTML = '';
      document.getElementById('postfiles').onclick = function () {//點選開始上傳
        var url = '/im/VersionManage/getSignature';
        var url1 = '/im/VersionManage/downLoadUrlTest';
        send_request({//這裡是點選上傳獲取簽名等資訊之後阿里雲利用Plupload元件進行post請求上傳檔案
          url: url,
          metod: "GET",
          async: false,
          success: function (data) {//獲取到後臺返回引數後進行賦值
            var d = JSON.parse(data).data
            accessid = d.accessid;
            policyBase64 = d.policy;
            signature = d.signaturecom;
            host = d.host;
            set_upload_param(uploader, '', false);//這一步是給g_object_name賦值的,如果不先執行這一步下面data上傳的key值就為空
            send_request({//封裝的ajax呼叫,後臺會獲取到阿里雲返回的檔案url,前端請求該後臺介面獲取url,以下程式碼都是根據實際專案需求寫的程式碼。
              url: url1,
              method: 'GET',
              data: {key: g_object_name},
              async: false,
              success: function (data) {
                console.log(g_object_name)
                if (JSON.parse(data).code == 1 && g_object_name !== '') {//此判斷條件是為了防止使用者直接點選開始上傳給予提示
                  new_file_name = g_object_name;
                  document.getElementById('ossfile').setAttribute("data-name", new_file_name)//設定自定義屬性,讓package_url能獲取到新生成的檔名
                  console.log(JSON.parse(data).data)//獲取到阿里雲返回的url
                }else{
                  parent.modal.operModal({
                    info: '請選擇檔案',
                    className: 'WaitPay'
                  });
                }
              }
            })
          },
        });
        return false;
      };
    },

    FilesAdded: function (up, files) {//上傳檔名、大小、進度條提示標籤
      plupload.each(files, function (file) {
        key = file.name
        // console.log(new_file_name)
        document.getElementById('ossfile').innerHTML += '<div id="' + file.id + '">' + '<b></b>'
          + '<span class="versionurl">' + file.name + '</span>'
          + '<span class="size">' + '(' + plupload.formatSize(file.size) + ')' + '</span>'
          + '<div class="progress"><div class="progress-bar" style="width: 0%"></div></div>'
          + '</div>';
        $("#versionurl").val(file['name']);//這裡是根據專案需求新增的jquery程式碼
        $('#upPackgeUrl').attr('disabled', 'disabled');
      });
    },

    BeforeUpload: function (up, file) {
      // check_object_radio();
      set_upload_param(up, file.name, true);
    },

    UploadProgress: function (up, file) {
      var d = document.getElementById(file.id);
      d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
      var prog = d.getElementsByTagName('div')[0];
      var progBar = prog.getElementsByTagName('div')[0]
      progBar.style.width = 2 * file.percent + 'px';
      progBar.setAttribute('aria-valuenow', file.percent);
    },

    FileUploaded: function (up, file, info) {
      // console.log(file.name)
      if (info.status == 200) {
        console.log(up, file, info)
        document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '上傳成功';//這裡根據專案需求刪除了一點程式碼,具體可參考原始碼
      }
      else if (info.status == 203) {
        document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '上傳到OSS成功,但是oss訪問使用者設定的上傳回調伺服器失敗,失敗原因是:' + info.response;
      }
      else {
        document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response;
      }
    },

    Error: function (up, err) {
      if (err.code == -600) {
        document.getElementById('console').appendChild(document.createTextNode("\n選擇的檔案太大了,可以根據應用情況,在upload.js 設定一下上傳的最大大小"));
      }
      else if (err.code == -601) {
        document.getElementById('console').appendChild(document.createTextNode("\n選擇的檔案字尾不對,可以根據應用情況,在upload.js進行設定可允許的上傳檔案型別"));
      }
      else if (err.code == -602) {
        document.getElementById('console').appendChild(document.createTextNode("\n這個檔案已經上傳過一遍了"));
      }
      else {
        document.getElementById('console').appendChild(document.createTextNode("\nError xml:" + err.response));
      }
    }
  }
});

uploader.init();