阿里雲OSS web端直傳 不依賴官方pupload的插件

前言

作好了七牛雲存儲,又要換阿里雲oss。。。哎。。。
記錄一下過程。本次採用的是服務端生成簽名。web端直傳的方式。沒設置回調php

1、準備工做

瀏覽使用手冊:

阿里雲oss使用文檔html

幾個關鍵的手冊頁面:

一、服務端簽名後直傳
二、php代碼示例
三、PostObject API 說明前端

2、原理

一、用戶發送上傳Policy請求到應用服務器。
二、應用服務器返回上傳Policy和簽名給用戶。
三、用戶直接上傳數據到OSS
(我是直接把簽名生成到web頁面)web

3、開始開發

下載官方php demo。
在這裏插入圖片描述
打開demo中的get.php,如圖。
可見,就是咱們輸入本身oss的一些配置信息,而後返回reponse數組。我理解爲reponse這個數組就是返回的簽名。
在這裏插入圖片描述
上面的配置信息均可以寫入數據庫中,而後從數據庫讀取。。
例如:
在這裏插入圖片描述ajax

4、後端代碼:

採用的是thinkphp5框架開發。
從數據庫裏面把配置讀出來,而後複製上面demo的代碼,返回reponse數組到前端。
這裏是上傳兩個文件。一個到公共bucket,一個到私有bucket。因此。reponse數組會多了幾個參數。thinkphp

public function oss_addStep(){

        function gmt_iso8601($time) {
            $dtStr = date("c", $time);
            $mydatetime = new \DateTime($dtStr);
            $expiration = $mydatetime->format(\DateTime::ISO8601);
            $pos = strpos($expiration, '+');
            $expiration = substr($expiration, 0, $pos);
            return $expiration."Z";
        }

        $ossData = Db::name('oss_setting')->find();
        if(!$ossData){
            $this->error('請先配置OSS配置');
        } 
        $id = $ossData['access_key'];
        $key = $ossData['secret_key'];
        // $id= '<yourAccessKeyId>';          // 請填寫您的AccessKeyId。
        // $key= '<yourAccessKeySecret>';     // 請填寫您的AccessKeySecret。
        $bucket1 = $ossData['bucket1'];
        $bucket2 = $ossData['bucket2'];
        $domain1 = $ossData['domain1'];
        $domain2 = $ossData['domain2'];
        // $host的格式爲 bucketname.endpoint,請替換爲您的真實信息。
        $host1 = 'http://'.$bucket1.'.'.$domain1; 
        $host2 = 'http://'.$bucket2.'.'.$domain2; 
        // $callbackUrl爲上傳回調服務器的URL,請將下面的IP和Port配置爲您本身的真實URL信息。
       
        $dir1 = '';
        $dir2 = '';          // 用戶上傳文件時指定的前綴。;

        $now = time();
        $expire = 100;  //設置該policy超時時間是10s. 即這個policy過了這個有效時間,將不能訪問。
        $end = $now + $expire;
        $expiration = gmt_iso8601($end);


        //最大文件大小.用戶能夠本身設置
        $condition = array(0=>'content-length-range', 1=>0, 2=>1048576000);
        $conditions[] = $condition; 

        // 表示用戶上傳的數據,必須是以$dir開始,否則上傳會失敗,這一步不是必須項,只是爲了安全起見,防止用戶經過policy上傳到別人的目錄。
        $start = array(0=>'starts-with', 1=>'$key', 2=>$dir1);
        $conditions[] = $start; 


        $arr = array('expiration'=>$expiration,'conditions'=>$conditions);
        $policy = json_encode($arr);
        $base64_policy = base64_encode($policy);
        $string_to_sign = $base64_policy;
        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));

        $condition2 = array(0=>'content-length-range', 1=>0, 2=>1048576000);
        $conditions2[] = $condition2;
        $start2 = array(0=>'starts-with', 1=>'$key', 2=>$dir2);
        $conditions2[] = $start2;
        $arr2 = array('expiration'=>$expiration,'conditions'=>$conditions2);
        $policy2 = json_encode($arr2);
        $base64_policy2 = base64_encode($policy2);
        $string_to_sign2 = $base64_policy2;
        $signature2 = base64_encode(hash_hmac('sha1', $string_to_sign2, $key, true));

        $response = array();
        $response['accessid'] = $id;
        $response['host1'] = $host1;
        $response['host2'] = $host2;
        $response['policy'] = $base64_policy;
        $response['policy2'] = $base64_policy2;
        $response['signature'] = $signature;
        $response['signature2'] = $signature2;
        $response['expire'] = $end;
        $response['dir1'] = $dir1;  // 這個參數是設置用戶上傳文件時指定的前綴。
        $response['dir2'] = $dir2;  // 這個參數是設置用戶上傳文件時指定的前綴。


        $this->assign('response',$response);
        return $this->fetch();
    }

5、前端代碼:

必需要設置好bucket的跨域規則。
在這裏插入圖片描述
開post權限數據庫

把reponse數組的參數渲染到模板中。json

至於爲何這樣寫呢。。請細看阿里雲官方的 API PostObject
<form action=" method="post" class="ajaxForm2" id="form1">
          <input type="hidden" name="OSSAccessKeyId" id="accessid" value="{$response.accessid}">
          <input type="hidden" name="policy" id="policy" value="{$response.policy}">
          <input type="hidden" name="signature" id="signature" value="{$response.signature}">
          <input type="hidden" name="expire" id="expire" value="{$response.expire}">
          <input type="hidden" name="success_action_status" id="success_action_status" value="200">
          <input type="hidden" name="key" id="key1_name" value="">
          <input type="file"  style="display: none;" name="file" id="file1" value=""  class="" >
          
</form>
<form action="" method="post" class="ajaxForm2" id="form2">
          <input type="hidden" name="OSSAccessKeyId" id="accessid" value="{$response.accessid}">
          <input type="hidden" name="policy" id="policy" value="{$response.policy2}">
          <input type="hidden" name="signature" id="signature" value="{$response.signature2}">
          <input type="hidden" name="expire" id="expire" value="{$response.expire}">
          <input type="hidden" name="success_action_status" id="success_action_status" value="200">
          <input type="hidden" name="key" id="key2_name" value="">
          <input type="file"  style="display: none;" name="file" id="file2" value=""  class=""  />
          
</form>

效果如圖:後端

ajax 部分:api

$.ajax({
                url : '{$response.host1}',
                type : 'post',
                data : new FormData($('#form1')[0]),
                dataType:'XML',
                processData: false,
                contentType: false,
                error:function(xml){
                    console.log(xml.responseText);
                     layer.msg('上傳失敗');
                },
                success:function(){
                    $("#key1").val(key_name);
                    $("#up_key1").val(key_name);
                   layer.msg('上傳成功');
                }
            })
最後把key(文件名)存到數據庫。
獲取文件:從數據庫查出key,再用阿里雲官方的php sdk生成瀏覽地址,或者下載地址就能夠獲取到咱們想要的文件了。
先寫成這樣。。。
相關文章
相關標籤/搜索