<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Upload files to aliyunOSS with bootstrap-fileinput

      本文主要涉及兩個概念:

      • 阿里云OSS:對象存儲(Object Storage Service,簡稱OSS),是阿里云對外提供的海量、安全和高可靠的云存儲服務。
      • bootstrap-fileinput:An enhanced HTML 5 file input for Bootstrap 3.x with file preview for various files, offers multiple selection, and more.

      客服稱OSS不限制上下行流量,而且不占用ECS帶寬,所以將靜態(tài)文件存放在OSS是個不錯的選擇。除了放置站點引用的資源文件外,主要用于用戶文件的上傳。阿里云提供了Web端直傳方式,文件不經過站點服務器,不影響站點的性能和帶寬。真正擼代碼時,遇到了不少坑,而官方文檔秉承阿里一貫的程序員風格,天馬行空毫不連貫,博主東拼西湊才理順各細節(jié),關鍵點記錄如下,供需要的朋友參考。


      阿里官方沒有提供.NET的demo,找到Post Object,該文檔描述了提交的各參數(shù)。進行Post操作要求對bucket有寫權限,如果bucket為public-read-write,可以不上傳簽名信息,否則要求對該操作進行簽名驗證。與Put操作不同,Post操作使用AccessKeySecret對policy進行簽名計算出簽名字符串作為Signature表單域的值,OSS會驗證該值從而判斷簽名的合法性(不需要遵循用戶簽名驗證(Authentication)的規(guī)定,另外在header或url中加上簽名)。policy又是啥呢?Post請求的policy表單域用于驗證請求的合法性。 policy為一段經過UTF-8和base64編碼的JSON文本,聲明了Post請求必須滿足的條件(文件大小、一些http頭等,還有該條件的過期時間)。雖然對于public-read-write的bucket上傳時,post表單域為可選項(其它情況,因為需要簽名驗證,所以是必選項),也強烈建議使用該域來限制Post請求。

      so,第一步,構造Post條件,對于不同bucket,可以有不同的條件,可以寫在web.config中,如果經常變動,也可以寫在數(shù)據(jù)庫中方便管理。

       然后,給前端提供一個獲取policy的接口,代碼就不貼了,使用官方提供的SDK,很簡單。這里假設接口名稱為GetPolicyForOSSUpload,返回結果是:

      Data = new ModelForOSSUpload
      {
          AccessKeyId = aliyunconfig.AccessKeyId,
          PolicyBase64 = encodedPolicy,
          Signature = signature,
          Expiration = expiration
      }

      注意,expiration已經被用于構造PolicyBase64了,這里又單獨給個字段返回,是給前端用的,在有效時間內,不用再調該接口,能減輕服務器壓力一點是一點。

      前端js是這樣的:

       1 _getUploadPreSetting: function (bucketKey, policyName) {
       2     var presetting = {}, error = {}, self = this;
       3     var inner_getUploadPreSetting = function () {
       4         var now = new Date();
       5         if (!presetting.Expiration || presetting.Expiration < now) {
       6             presetting = {};
       7             error = {};
       8             $.ajax({
       9                 url: self._ossOpts.uploadPreSettingUrl,
      10                 type: 'GET',
      11                 async: false,
      12                 data: { bucketKey: bucketKey, policyName: policyName },
      13                 success: function (result) {
      14                     if (result.IsSucceed) {
      15                         presetting = result.Data;
      16                         //應付/Date(1460817323032)/這種奇葩格式
      17                         presetting.Expiration = eval('new ' + (presetting.Expiration.replace(/\//g, '')));
      18                     }
      19                     else {
      20                         error = result;
      21                     }
      22                 },
      23                 error: function (xhr, msg) {
      24                     error = { IsSucceed: false, Message: msg };
      25                 }
      26             });
      27         }
      28         return presetting || error;
      29     };
      30     return inner_getUploadPreSetting;
      31 }

      此處用了閉包,這是因為不同的policy,我們以bucketKey和policyName進行區(qū)分(看貼出來的web.config片段),如果一個頁面需要多個policy,每個policy都要對應一個變量,數(shù)量不定的情況下,我們也不能硬編碼,同時為了讓它們互不影響,就采用了閉包的方式。調用如下:

      var getUploadPreSetting = this._getUploadPreSetting(this._ossOpts.bucketKey, this._ossOpts.policyName);
      var presetting = getUploadPreSetting();

      policy的部分到此為止,下面我們來看下bootstrap-fileinput這個組件,并對它進行一點點改造,以便于符合OSS的上傳規(guī)則。


      除了文件數(shù)據(jù),提交時還要附加OSS要求的一些表單域,比如剛才講的policy、Signature,還可以給每個文件加上cache-Control、callback(上傳成功后,OSS回調我們的接口地址)等。我們在初始化bootstrap-fileinput(下稱fileinput)時可以傳入一個uploadExtraData配置項(函數(shù)或對象),在上傳每個文件時,fileinput會調用uploadExtraData,將獲取到的數(shù)據(jù)附加到文件數(shù)據(jù)后一起上傳。然而這就存在一個問題了,OSS文檔中說“文件或文本內容,必須是表單中的最后一個域。”,否則會返回“The bucket POST must contain the specified 'key'. If it is specified, please check the order of the fields”的錯誤信息。

      題外話:關于表單域順序的說明,以前文檔中并沒有,還是博主在一次工單提交和差點投訴后才加上去的,當時很奇怪難道沒人遇到過,還是說這樣用OSS的人不多?另外在和客服扯皮的同時,博主也上網搜了一把,發(fā)現(xiàn)AWS的用戶竟然也遇到類似問題,請看 InvalidArgumentBucket POST must contain a field named 'key'. If it is specified, please check the order of the fields.keyB,連返回的錯誤消息都大同小異,博主大膽猜測,阿里云和AWS的數(shù)據(jù)存儲用的是同一套組件,還是開源的,博主知識淺陋,有知道的朋友說一聲。

      于是只能去看fileinput的源碼了,幸好它是開源的,我們只需要改動一下_uploadSingle函數(shù)的末尾:

      self._uploadExtra(previewId, i); //新加
      formdata.append(self.uploadFileAttr, files[i], self.filenames[i]); //文件數(shù)據(jù)
      formdata.append('file_id', i);
      self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, previewId, i, true); //也要改造下_ajaxSubmit,傳入true表示額外數(shù)據(jù)不再附加

      _ajaxSubmit也改造了下,圓圈內為新加:

      fileinput改造完畢,so easy!那么當上傳成功后,我們一般都是要對應用數(shù)據(jù)做一些處理,比如更新數(shù)據(jù)庫中的url地址什么的,我們可以獲取響應信息,然后再調用相應的后臺接口,OSS也提供了直接回調的方式,后者能傳遞更多關于文件的信息,并且在構造callback時可自定義參數(shù),因此更靈活,方便后臺回調接口的數(shù)據(jù)處理,具體可看Callback。


      下例,前端js:

      callback:{
          "callbackUrl":GlobalConfig.siteurl+'Merchandise/SetMerchandisePicUrl',
          "callbackBody":"merchandiseid="+vm.merchandise.BasicInfo.ID+"&picname=${object}"
      }

      后端回調接口:

       1 [AllowAnonymous]
       2 public async Task<ActionResult> SetMerchandisePicUrl(int merchandiseid, string picname)
       3 {
       4     var aliyunconfig = MvcApplication.AliyunConfig;
       5     var bucket = aliyunconfig.OSS.Buckets["merchandise_pictures"];
       6     var picUri = $"http://{ bucket.Value}.{aliyunconfig.OSS.ImgEndpoint}/{picname}";
       7     await MerchandiseContext.AppendPicUri(merchandiseid, picUri);
       8     return this.Json(new
       9     {
      10         initialPreview = new string[] { picUri },                
      11         initialPreviewConfig = new List<object> {
      12                 new {
      13                     caption = picname,
      14                     //width ="160px", //并沒有什么用
      15                     url =Url.Action("RemoveMerchandisePicUrl"),
      16                     extra = new {picUri= picUri,merchandiseid = merchandiseid}
      17                 }
      18         }
      19     });
      20 }

      接口允許匿名,便于OSS調用,為了防止惡意調用,最好進行簽名校驗。fileinput根據(jù)返回結果判斷是否上傳成功(沒有error屬性表示上傳成功),若成功且結果里有initialPreview[和initialPreviewConfig]等屬性,則將這些屬性應用到對應文件顯示。特別注意initialPreviewConfig中的url和extra屬性,表示刪除該文件時調用的接口和傳遞的參數(shù)。

      另外,若我們不指定回掉地址,那么OSS默認會返回空文檔(在上傳成功的情況下),若需要讓其返回官方文檔中提到的PostResponse,需要指定success_action_status為201。


      其它參考資料:

      理解DOMString、Document、FormData、Blob、File、ArrayBuffer數(shù)據(jù)類型

      Web 前沿——HTML5 Form Data 對象的使用

       

      轉載請注明本文出處:http://www.rzrgm.cn/newton/p/6066020.html

      posted @ 2016-11-17 15:27  萊布尼茨  閱讀(3687)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 亚洲日韩久热中文字幕| 久热久精久品这里在线观看| 久久久久久亚洲精品成人| 老少配老妇老熟女中文普通话| 乌鲁木齐县| 国产精品无遮挡在线观看| 曰韩亚洲AV人人夜夜澡人人爽| 亚洲欧美自偷自拍视频图片| 亚洲国产婷婷综合在线精品| av日韩精品在线播放| 性做久久久久久久久| 大陆一级毛片免费播放| 亚洲成av人片一区二区| 国产精品成人午夜福利| 色综合欧美亚洲国产| 高清国产一区二区无遮挡| 宾馆人妻4P互换视频| 蜜臀在线播放一区在线播放| 精品无码久久久久久久久久| 性欧美三级在线观看| 亚洲激情一区二区三区在线| 国产精品人成视频免费播放| 国产精品国产三级国av| 日本不卡片一区二区三区| av中文无码乱人伦在线观看| 亚洲av片在线免费观看| 思热99re视热频这里只精品| 久久亚洲精品中文字幕馆| 人妻精品久久无码专区涩涩| 久热天堂在线视频精品伊人| 最近中文字幕完整版2019| 欧美日本一区二区视频在线观看| 亚洲一区中文字幕第十页| 97人人添人澡人人爽超碰| 国色精品卡一卡2卡3卡4卡在线| 东京热人妻无码一区二区av| 日韩精品国产另类专区| 两个人免费完整高清视频| 亚洲av免费成人在线| 激情综合网激情五月我去也| 亚洲丶国产丶欧美一区二区三区|