第一次寫博客,如有錯誤請多多指教。
先上代碼吧:
1 ossUpload = function (file, fun, funParameter) { 2 //第一此請求后台服務器獲取認證請求 3 $.ajax({ 4 url: "/UEditor/GetSecurityToken", 5 type: "post", 6 success: function (data) { 7 var access = JSON.parse(data); 8 console.log(access); 9 let host = access.Host; 10 var myDate = new Date().format("yyyyMMddhhmmss"); 11 var policyBase64 = Base64.encode(JSON.stringify(myDate)) 12 var name = Base64.encode(JSON.stringify(myDate)) 13 var name = Crypto.HMAC(Crypto.SHA1, policyBase64, name); 14 var g_object_name = access.Object_name + "/" + name+"."+file.type.split('/')[1] 15 var request = new FormData(); 16 request.append('id', "file_0"); 17 request.append("OSSAccessKeyId", access.AccessKeyId); //Bucket 擁有者的Access Key Id。 18 request.append("policy", access.Policy); //policy規定了請求的表單域的合法性 19 request.append("Signature", access.Signature); //根據Access Key Secret和policy計算的簽名信息,OSS驗證該簽名信息從而驗證該Post請求的合法性 20 request.append('x-oss-security-token', access.SecurityToken); 21 //---以上都是阿里的認證策略 22 request.append("key", g_object_name); //文件名字,可設置路徑 23 request.append("success_action_status", '200'); // 讓服務端返回200,不然,默認會返回204 24 request.append('file', file); //需要上傳的文件 file 25 console.log(request); 26 //正式上傳請求 27 $.ajax({ 28 url: host, //上傳阿里地址 29 data: request, 30 processData: false, //默認true,設置為 false,不需要進行序列化處理 31 cache: false, //設置為false將不會從瀏覽器緩存中加載請求信息 32 async: false, //發送同步請求 33 contentType: false, //避免服務器不能正常解析文件---------具體的可以查下這些參數的含義 34 dataType: 'xml', //不涉及跨域 寫json即可 35 type: 'post', 36 success: fun(funParameter, host, g_object_name), 37 error: function (returndata) { 38 console.log(arguments) 39 alert("上傳圖片出錯", false); 40 } 41 }); 42 } 43 }) 44 } 45 //格式化時間 46 Date.prototype.format = function (fmt) { 47 var o = { 48 "M+": this.getMonth() + 1, //月份 49 "d+": this.getDate(), //日 50 "h+": this.getHours(), //小時 51 "m+": this.getMinutes(), //分 52 "s+": this.getSeconds(), //秒 53 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 54 "S": this.getMilliseconds() //毫秒 55 }; 56 if (/(y+)/.test(fmt)) { 57 fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 58 } 59 for (var k in o) { 60 if (new RegExp("(" + k + ")").test(fmt)) { 61 fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 62 } 63 } 64 return fmt; 65 }
上傳用的是sts上傳還需要在阿里雲進行一系列的授權管理,最后得到AccessKeyId,AccessKeySecret用來請求已經授權的角色(RoleArn)當然還需要REGIONID(地區對應ID 例:cn-beijing),ENDPOINT(請求接口 例:sts.cn-beijing.aliyuncs.com)
這一步sts請求是在后台進行的我后台用的是.net core,還需要引用aliyun-net-sdk-sts上一份后端的代碼
1 public class AliyunAcsStsConfig 2 { 3 /// <summary> 4 /// 地區 5 /// </summary> 6 public string REGIONID { get; set; } 7 /// <summary> 8 /// 訪問阿里雲的地址 9 /// </summary> 10 public string ENDPOINT { get; set; } 11 /// <summary> 12 /// 配置的ram 13 /// </summary> 14 public string RoleArn { get; set; } 15 /// <summary> 16 /// 會話的名稱可自定義 17 /// </summary> 18 public string RoleSessionName { get; set; } 19 /// <summary> 20 /// 該權限用戶的密碼 21 /// </summary> 22 public string AccessKeySecret { get; set; } 23 /// <summary> 24 /// 該權限的用戶ID 25 /// </summary> 26 public string AccessKeyId { get; set; } 27 /// <summary> 28 /// 上傳路徑 29 /// https://Bucket名稱.oss-cn-beijing.aliyuncs.com 30 /// </summary> 31 public string upload { get; set; } 32 /// <summary> 33 /// 文件存儲路徑 34 /// ***/****/ 35 /// </summary> 36 public string path { get; set; } 37 }
private readonly UEditorService _ueditorService; private readonly AliyunAcsStsConfig stsConfig; public UEditorController(UEditorService ueditorService, IOptions<AliyunAcsStsConfig> stsConfig) { this._ueditorService = ueditorService; this.stsConfig = stsConfig.Value; }
string REGIONID = stsConfig.REGIONID; string ENDPOINT = stsConfig.ENDPOINT; // 構建一個 Aliyun Client, 用於發起請求 // 構建Aliyun Client時需要設置AccessKeyId和AccessKeySevcret DefaultProfile.AddEndpoint(REGIONID, REGIONID, "Sts", ENDPOINT); IClientProfile profile = DefaultProfile.GetProfile(REGIONID, stsConfig.AccessKeyId, stsConfig.AccessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); // 構造AssumeRole請求 AssumeRoleRequest request = new AssumeRoleRequest(); request.AcceptFormat = FormatType.JSON; // 指定角色Arn request.RoleArn = stsConfig.RoleArn; request.RoleSessionName = stsConfig.RoleSessionName; // 可以設置Token有效期,可選參數,默認3600秒; // request.DurationSeconds = 3600; // 可以設置Token的附加Policy,可以在獲取Token時,通過額外設置一個Policy進一步減小Token的權限; // request.Policy="<policy-content>" String dt = DateTime.Now.AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss.000Z"); object[,] ob = { { "content-length-range", 0, 1048576000 } }; AssumeRoleResponse response = client.GetAcsResponse(request); ImgUploadAccess access = new ImgUploadAccess(); access.AccessKeyId = response.Credentials.AccessKeyId; access.AccessKeySecret = response.Credentials.AccessKeySecret; access.SecurityToken = response.Credentials.SecurityToken; string str = JsonConvert.SerializeObject(new Policy { expiration=dt, conditions=ob }); byte[] b = Encoding.Default.GetBytes(str); string base64 = Convert.ToBase64String(b); HMACSHA1 hmacsha1 = new HMACSHA1(); hmacsha1.Key= Encoding.UTF8.GetBytes(access.AccessKeySecret); byte[] hashBytes = hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(base64)); access.Policy = base64; access.Signature =Convert.ToBase64String(hashBytes); access.Object_name = stsConfig.path+DateTime.Now.ToString("yyyyMM"); access.Host = stsConfig.imgupload; return JsonConvert.SerializeObject(access);
1 public class ImgUploadAccess 2 { 3 public string AccessKeyId { get; set; } 4 public string AccessKeySecret { get; set; } 5 public string SecurityToken { get; set; } 6 public string Host { get; set; } 7 public string Signature { get; set; } 8 public string Policy { get; set; } 9 public string Object_name { get; set; } 10 } 11 public class Policy 12 { 13 public string expiration { get; set; } 14 public object[,] conditions { get; set; } 15 }
這樣上傳功能基本上搞定了