OSS的簡單使用


OSS簡介

Object Storage Service,簡稱 OSS,是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。

它具有與平台無關的RESTful API接口,能夠提供99.999999999%的服務持久性。

使用場景:

  • 圖片分享

  • 熱點視頻

優勢:

  • 成本低(40G才6元,比ECS便宜太多)
  • 不會影響ECS帶寬
  • 和服務器解耦

下面介紹一些基本功能:

  • 初始化

  • 創建存儲空間

  • 上傳文件

  • 跨域訪問設置

  • 設置讀寫權限

OSS使用(NET SDK使用)

1.初始化

創建一個OssClient,就可以很方便的調用OSS的方法。

       const string accessKeyId = "xxxxxxxxx";				    
       const string accessKeySecret = "xxxxxxxxxx"; 
       const string endpoint = "oss-cn-beijing.aliyuncs.com";			//OSS對應的區域地址
       private static OssClient ossClient = new OssClient(endpoint, accessKeyId, accessKeySecret);

2.創建存儲空間

很簡單,只需要調用OssClient.CreateBucket

   ossClient.CreateBucket("myBucket");		//新建一個Bucket

3.設置讀寫權限

調用OssClient.SetBucketAcl

   ossClient.SetBucketAcl("myBucket", CannedAccessControlList.PublicRead);	//設置為公共讀

CannedAccessControlList有三個屬性:Private(私有),PublicRead(公共讀),PublicReadWrite(公共讀寫)

4.跨域訪問設置

調用OssClient.SetBucketCors

   var req = new SetBucketCorsRequest("myBucket");
   var rule = new CORSRule();
   //指定允許跨域請求的來源
   rule.AddAllowedOrigin("*");
   //指定允許的跨域請求方法(GET/PUT/DELETE/POST/HEAD)
   rule.AddAllowedMethod("POST");
   //控制在OPTIONS預取指令中Access-Control-Request-Headers頭中指定的header是否允許。
   rule.AddAllowedHeader("*");

   req.AddCORSRule(rule);
   ossClient.SetBucketCors(req);

5.上傳文件

調用OssClient.PutObject

   var result = ossClient.PutObject("myBucket", "111.mp4", @"d:\237badef-0f6d-4a8e-a634-a44c9704b6e6.mp4");
   Console.WriteLine(result.ETag);

6.列出存儲空間中的所有文件

調用ossClient.ListObjects

   var listObjectsRequest = new ListObjectsRequest("myBucket");
   var result = ossClient.ListObjects(listObjectsRequest);
   Console.WriteLine("List objects succeeded");
   foreach (var summary in result.ObjectSummaries)
   {
       Console.WriteLine("File name:{0}", summary.Key);
   }

以上步驟1到4,可以在OSS管理后端完成

WEB端直傳

剛開始使用OSS的時候,是采用前端將文件流上傳到Web服務器,然后通過Web服務器再上傳到OSS

這種做法有三個缺點:

  • 第一:上傳慢。先上傳到應用服務器,再上傳到OSS,網絡傳送多了一倍。如果數據直傳到OSS,不走應用服務器,速度將大大提升,而且OSS是采用BGP帶寬,能保證各地各運營商的速度。
  • 第二:擴展性不好。如果后續用戶多了,應用服務器會成為瓶頸。
  • 第三:費用高。由於OSS上傳流量是免費的。如果數據直傳到OSS,不走應用服務器,那么將能省下幾台應用服務器

如何操作?

1.通過JS控件直傳

  • 采用plupload 直接提交表單數據(即PostObject)到OSS;
  • 在JS端,輸入OSS的認證信息(不安全)
   var policyText = {
       "expiration": "2020-01-01T12:00:00.000Z", //設置該Policy的失效時間,超過這個失效時間之后,就沒有辦法通過這個policy上傳文件了
       "conditions": [
       ["content-length-range", 0, 1048576000] // 設置上傳文件的大小限制
       ]
   };

   accessid= '6MKOqxGiGU4AUk44';
   accesskey= 'ufu7nS8kS59awNihtjSonMETLI0KLy';
   host = 'http://post-test.oss-cn-hangzhou.aliyuncs.com';

   var policyBase64 = Base64.encode(JSON.stringify(policyText))
   message = policyBase64
   var bytes = Crypto.HMAC(Crypto.SHA1, message, accesskey, { asBytes: true }) ;
   var signature = Crypto.util.bytesToBase64(bytes);
   var uploader = new plupload.Uploader({
   	runtimes : 'html5,flash,silverlight,html4',
   	browse_button : 'selectfiles', 
   	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 : host,
   	multipart_params: {
   		'Filename': '${filename}', 
           'key' : '${filename}',
   		'policy': policyBase64,
           'OSSAccessKeyId': accessid, 
           'success_action_status' : '200', //讓服務端返回200,不然,默認會返回204
   		'signature': signature,
   	},

   	init: {
   		PostInit: function() {
   			document.getElementById('ossfile').innerHTML = '';
   			document.getElementById('postfiles').onclick = function() {
   				uploader.start();
   				return false;
   			};
   		},

   		FilesAdded: function(up, files) {
   			plupload.each(files, function(file) {
   				document.getElementById('ossfile').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>'
   				+'<div class="progress"><div class="progress-bar" style="width: 0%"></div></div>'
   				+'</div>';
   			});
   		},

   		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) {
               //alert(info.status)
               if (info.status >= 200 || info.status < 200)
               {
                   document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'success';
               }
               else
               {
                   document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response;
               } 
   		},

   		Error: function(up, err) {
   			document.getElementById('console').appendChild(document.createTextNode("\nError xml:" + err.response));
   		}
   	}
   });

   uploader.init();

具體可以下載OSS官網的 [例子]:https://help.aliyun.com/document_detail/31925.html?spm=a2c4g.11186623.6.629.AdgPho

2.通過服務端構建認證信息(安全,參看下一小節)

服務端構建認證信息

上一小節中,通過JS來上傳文件,雖然可以上傳,但是AppSecret會泄露,不安全。所以需要在服務端將認證信息構建出來,再給到前端

        public virtual ActionResult GetPostPolicy()
        {
            string host = "http://" + bucket + "."+ endpoint;
            //第一步,構造policy
            //var dir = "zhangsan/";//設置用戶上傳指定的前綴,必須以斜線結尾
            var expiration = DateTime.Now.AddMinutes(100);
            var policyConds = new PolicyConditions();
            //policyConds.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, dir);//上傳目錄
            policyConds.AddConditionItem(PolicyConditions.CondContentLengthRange, 1, 1048576000);//允許上傳的文件大小限制
            var postPolicy = ossClient.GeneratePostPolicy(expiration, policyConds);//給policyConds添加過期時間並json序列化(格式iso8601:"yyyy-MM-dd'T'HH:mm:ss.fff'Z'")
    
            //第二步 將policy 的json字符串進行base64編碼
            var base64Policy = Convert.ToBase64String(Encoding.UTF8.GetBytes(postPolicy));
    
            //第三步,生成簽名
            var signature = ComputeSignature(accessKeySecret, base64Policy);//生成簽名
    
            //以下返回給前端
            TimeSpan ts = expiration - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            var expire = Convert.ToInt64(ts.TotalSeconds);
    
            Dictionary<string, object> response = new Dictionary<string, object>();
            response["accessid"] = accessKeyId;
            response["host"] = host;
            response["policy"] = base64Policy;
            response["signature"] = signature;
            response["expire"] = expire;
            return ResponseSuccess(response);		//返回json,可以自己修改(該方法是自己封裝的)
        }

        private static string ComputeSignature(string key, string data)
        {
            using (var algorithm = KeyedHashAlgorithm.Create("HmacSHA1".ToUpperInvariant()))
            {
                algorithm.Key = Encoding.UTF8.GetBytes(key.ToCharArray());
                return Convert.ToBase64String(
                    algorithm.ComputeHash(Encoding.UTF8.GetBytes(data.ToCharArray())));
            }
        }

再結合剛才的前端,修改如下

<script type="text/javascript">
    var  accessid= '';
    var host = 'http://muBucket.oss-cn-beijing.aliyuncs.com';
    var policyBase64 = '';
    var signature = '';
    var uploadFileName='';			//文件名稱
    //獲取隨機字符串
    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) {
        var pos = filename.lastIndexOf('.')
        suffix = ''
        if (pos != -1) {
            suffix = filename.substring(pos)
        }
        return suffix;
    }
    //設置plupload屬性
    function set_upload_param(up, filename, ret)
    {
        var suffix='';
        if (filename != '') {
            suffix = get_suffix(filename)
        }else{
            return;
        }
        uploadFileName=random_string(20)+suffix;
        new_multipart_params = {
            'key' : uploadFileName,
            'policy': policyBase64,
            'OSSAccessKeyId': accessid,
            'success_action_status' : '200', //讓服務端返回200,不然,默認會返回204
            'signature': signature,
        };
        up.setOption({
            'url': host,
            'multipart_params': new_multipart_params
        });
        up.start();
    }
    //初始化plupload控件
    var uploader = new plupload.Uploader({
        runtimes : 'html5,flash,silverlight,html4',
        browse_button : 'selectfiles',
        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',
        multi_selection:false,
        filters: {
            mime_types : [
                { title : "Video files", extensions : "mp4,rmvb" }
            ],
            max_file_size : '600000kb', //最大只能上傳600M的文件
            prevent_duplicates : true //不允許選取重復文件
        },
        url : host,
        init: {
            PostInit: function() {
                document.getElementById('ossfile').innerHTML = '';
                $.ajax({
                    type:'GET',
                    url:'GetPostPolicyURL',		//獲取認證信息的URL
                    success:function(res){
                        if(res.rspcode==="0000"){
                            accessid = res.accessid;
                            host = res.host;
                            policyBase64 =res.policy;
                            signature =res.signature;

                        }else{
                            /* 彈出框提示錯誤 */
                            toastr.error(res.rspmsg);
                        }
                    }
                })
            },

            FilesAdded: function(up, files) {
                plupload.each(files, function(file) {
                    set_upload_param(up, file.name, true);
                    document.getElementById('ossfile').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>'
                        +'<div class="progress"><div class="progress-bar" style="width: 0%"></div></div>'
                        +'</div>';
                });
            },

            BeforeUpload: function(up, file) {

            },

            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) {
                if (info.status >= 200 || info.status < 200)
                {
                    vm.formModel.VideoPath=uploadFileName;			//將文件名記錄下來,用於保存
                    document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'success';
                }
                else
                {
                    document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response;
                }
            },

            Error: function(up, err) {
                document.getElementById('console').appendChild(document.createTextNode("\nError xml:" + err.response));
            }
        }
    });

    uploader.init();

</script>

參考文章:

[OSS官網文檔]:https://help.aliyun.com/document_detail/31817.html?spm=a2c4g.11186623.6.539.PK7qiJ


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM