阿里oss 實現檔案上傳(前端程式碼)
阿新 • • 發佈:2019-01-03
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();