阿里云 oss 视频上传 sts+前端js分片上传

目录

第1步 必要参数获取

第2步 执行下面php后端请求接口代码的两个类进行sts获取令牌获取 

 2.1  php后端请求接口 

 2.2  返回结果

第3步  前端获通过js获取上面的返回的3个参数 实现分片上传

第4步 上传成功后异步回调处理


第1步 必要参数获取

参数名

参数说明

备注

Endpoint

Bucket域名

Bucketname

Bucket名称

用户名

子账号用户名

AccessKeyId

子账号keyid

-

AccessKeySecret

子账号秘钥

format格式 json或xml
version2015-04-012015-04-01
signaturemethodHMAC-SHA1
signatureversion1.0
actionAssumeRole
RoleArn
Bucketurl

*下面是我的配置信息可以参考(标红的需要更改自己的OSS配置)

[
    'bucket' => '',
    'endpoint' => '',
    'format' => 'json',
    'version' => '2015-04-01',
    'accesskeyid' => '',
    'ck' => '',
    'signaturemethod' => 'HMAC-SHA1',
    'signatureversion' => '1.0',
    'action' => 'AssumeRole',
    'RoleArn' => '',
    'Bucketurl'=> ''
]

*在走以下步骤之前先在你的阿里云oss中获取以上的参数信息因为下面步骤要用到

阿里云oss配置说明可参考:oss 参数配置说明_荣~博客的博客-CSDN博客_oss 参数


第2步 执行下面php后端请求接口代码的两个类进行sts获取令牌 

获取 AccessKeySecret 、AccessKeyId 、SecurityToken 这3个参数(sts)返回的结果(2.2小节)

  

    2.1  php后端请求接口 

*下面php代码直接复制到自己的服务器下是可以执行返回数据,需要把刚开始获取的配置参数bucket、endpoint、format、version、accesskeyid、ck、signaturemethod 、signatureversion 、action、RoleArn下面填上即可,有两处需要加上这些参数

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/7
 * Time: 17:43
 */
class sysshop_sts_util{

    //以下参数需要从自己的oss获取相对应的参数
    CONST bucket = '';
    CONST endpoint = '';
    CONST format = '';
    CONST version = '';
    CONST accesskeyid = '';

    //ck是秘钥
    CONST ck = '';
    CONST signaturemethod = '';
    CONST signatureversion = '';
    CONST action = '';
    CONST RoleArn = '';
    /**
     * 向oss端post请求
     * @param array $data
     */
    public function request_curl(array $data){
        $postUrl = 'https://sts.cn-beijing.aliyuncs.com';
        $curlPost = $data;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$postUrl);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
        $curlCallback  = curl_exec($ch);
        return $curlCallback;
        curl_close($ch);
    }

    /**
     * 获得签名信息
     * @param $get_key
     * @param $get_key_value
     * @return string
     */
    public function getsignature($get_key,$get_key_value)
    {
        sort($get_key);
        $StringToSign = 'POST&'.urlencode('/').'&';
        $q_str = '';
        foreach($get_key as $kval){
            $q_str .= urlencode($kval).'='.urlencode($get_key_value[$kval]).'&';
        }
        $q_str = substr($q_str,0,-1);
        $StringToSign .= urlencode($q_str);
        return $StringToSign;
    }

    /**
     * 获取参数key值
     * @return array
     */
    public function getkey()
    {
        $get_key = array(
            'Format',
            'Version',
            'AccessKeyId',
            'RoleArn',
            'RoleSessionName',
            'SignatureMethod',
            'Timestamp',
            'SignatureNonce',
            'SignatureVersion',
            'Action'
        );
        return $get_key;
    }

    /**
     * 获取参数数组
     * @param $RoleSessionName
     * @return array
     */
    public function getkeyvalue($RoleSessionName)
    {
        $h_8_time = time()-8*60*60;
        $get_key_value = array(
            'Format' => self::format,
            'RoleArn'=>self::RoleArn,
            'RoleSessionName'=>$RoleSessionName,
            'Action' => self::action,
            'Version' => self::version,
            'SignatureMethod' => self::signaturemethod,
            'SignatureNonce' => time(),
            'SignatureVersion' => self::signatureversion,
            'AccessKeyId' =>self::accesskeyid,
            'Timestamp' => date('Y-m-d',$h_8_time).'T'.date('H:i:s',$h_8_time).'Z'
        );
        return $get_key_value;
    }
}


/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/7
 * Time: 13:12
 */
class sysshop_sts_getToken{

    //以下参数需要从自己的oss获取相对应的参数
    CONST bucket = '';
    CONST endpoint = '';
    CONST format = '';
    CONST version = '';
    CONST accesskeyid = '';

    //ck是秘钥
    CONST ck = '';
    CONST signaturemethod = '';
    CONST signatureversion = '';
    CONST action = '';
    CONST RoleArn = '';
    private $format;
    private $version;
    private $accesskeyid;
    private $signature;
    private $signaturemethod;
    private $signatureversion;
    private $signaturenonce;
    private $timestamp;
    private $action;
    private $RoleArn;
    private $RoleSessionName;
    public function getformat()
    {
        return $this->format;
    }
    public function getversion()
    {
        return $this->version;
    }
    public function getaccesskeyid()
    {
        return $this->accesskeyid;
    }
    public function getsignature()
    {
        return $this->signature;
    }
    public function getsignaturemethod(){
        return $this->signaturemethod;
    }
    public function getsignatureversion(){
        return $this->signatureversion;
    }
    public function getsignaturenonce(){
        return $this->signaturenonce;
    }
    public function gettimestamp(){
        return $this->timestamp;
    }
    public function getaction(){
        return $this->action;
    }

    /**
     * @return string
     */
    public function getRoleArn()
    {
        return $this->RoleArn;
    }

    /**
     * @return string
     */
    public function getRoleSessionName()
    {
        return $this->RoleSessionName;
    }

    public function index($sessionname)
    {
        
        $sysshop_sts_util = new sysshop_sts_util();
        $this->RoleSessionName = $sessionname;
        $h_8_time = time()-8*60*60;
        $get_key = $sysshop_sts_util->getkey();
        $get_key_value = $sysshop_sts_util->getkeyvalue($this->RoleSessionName);
        $StringToSign = $sysshop_sts_util->getsignature($get_key,$get_key_value);
        $this->format = self::format;
        $this->version = self::version;
        $this->accesskeyid = self::accesskeyid;
        $ck = self::ck;
        $this->signature = base64_encode(hash_hmac("sha1",$StringToSign,$ck.'&',true));
        $this->signaturemethod = self::signaturemethod;
        $this->signatureversion = self::signatureversion;
        $this->signaturenonce = time();
        $this->timestamp = date('Y-m-d',$h_8_time).'T'.date('H:i:s',$h_8_time).'Z';
        $this->action = self::action;
        $this->RoleArn = self::RoleArn;
        return $sysshop_sts_util->request_curl($this->formatpostdata());

    }

    /**
     * 格式化参数
     * @return mixed
     */
    public function formatpostdata(){
        $data['Format'] = $this->getformat();
        $data['Version'] = $this->getversion();
        $data['AccessKeyId'] = $this->getaccesskeyid();
        $data['Signature'] = $this->getsignature();
        $data['SignatureMethod'] = $this->getsignaturemethod();
        $data['SignatureVersion'] = $this->getsignatureversion();
        $data['SignatureNonce'] = $this->getsignaturenonce();
        $data['Timestamp'] = $this->gettimestamp();
        $data['Action'] = $this->getaction();
        $data['RoleArn'] = $this->getRoleArn();
        $data['RoleSessionName'] = $this->getRoleSessionName();
        return $data;
    }
}
$sysshop_sts_getToken = new sysshop_sts_getToken();
$sessionname = 'test';
$callback = $sysshop_sts_getToken->index($sessionname);
print_r($callback);

 2.2  返回结果

         {
            "RequestId": "",
            "AssumedRoleUser": {
                "AssumedRoleId": "",
                "Arn": ""
                },
            "Credentials": {
                "
AccessKeySecret": "",
                "
AccessKeyId": "",
                "Expiration": "2018-10-17T03:17:31Z",
                "
SecurityToken":  ""           
               }
         }


第3步  前端获通过js获取上面的返回的3个参数 实现分片上传

*实际开发中遇到一个问题,在上传文件的时候出现了aliyun-oss-sdk-4.4.4.min.js这个文件js某些方法报错,之后修改了前端ajax请求方式例如jquery后端获取令牌接口的方式然后问题解决了,这一步也需要用到前面获取的参数,对应填好即可

<html>
<head>
   <script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-4.4.4.min.js"></script>
</head>
<body>
  <input type="file" id="file" />
  <script type="text/javascript">
      document.getElementById('file').addEventListener('change', function (e) {
      var file = e.target.files[0];

      // ① 上传文件名称自定义
      var storeAs = 'upload-file';
      console.log(file.name + ' => ' + storeAs);

      // ② 后端令牌获取接口请求 下面xxxxxx.php为上面1.2后端请求地址
      OSS.urllib.request("./xxxxxx.php",
                      {method: 'GET'}, 
                      function (err, response) {
          if (err) {
            return alert(err);
          }
          try {
            result = JSON.parse(response);
                  alert(result.Credentials.AccessKeySecret);
          } catch (e) {
            return alert('parse sts response info error: ' + e.message);
          }


          //③异步回调地址和传参 下面callbackUrl为第3步请求异步回调地址callbackBody参数可以根据自己网站业务自定义格式必须遵循下面的格式规范(例如在加一个username字段 &username=${x:username};别忘了在④中callbackval给变量赋值 )
          var callback={ 
              "callbackUrl":"www.xxxxxx.com/callback.php", 
              "callbackBody":"mobile=${x:mobile}&type=${x:type}" 
          } 
          //④定义callbackbody中需要替换的变量 
          var callbackvar ={ 
              "x:mobile":"13999999999", 
              "x:type":"1" 
          } 
          //64位编码 
          var parses = function(data){ 
            var base = new Base64();  
              var dataBase64 = base.encode(JSON.stringify(data)) 
              console.log(dataBase64) 
              return dataBase64; 
          } 
          var client = new OSS.Wrapper({

           //⑤请求后端获取令牌的3个参数 
            accessKeyId: result.Credentials.AccessKeyId,
            accessKeySecret: result.Credentials.AccessKeySecret,
            stsToken: result.Credentials.SecurityToken,

           //⑥此处填写自己的oss的endpoint 必填
            endpoint: '',

            //⑦此处填写自己的oss的bucket名称 必填
            bucket: ''
          });
  
          client.multipartUpload(storeAs, file, { 
    //headers 头参数添加 
    //x-oss-callback  定义的callbackurl+callbackbody  Base64编码后的值 
    //x-oss-callback-var  自定义参数值替换callbackbody 变量 
    headers: { 
      'x-oss-callback':parses(callback), 
      'x-oss-callback-var': parses(callbackvar) 
    } 
  }).then(function (res) {
            console.log(res)
          }).catch(function (err) {
            console.log(err);
          });
        });
    });

      function Base64() {  

    // private property  
    _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";  

    // public method for encoding  
    this.encode = function (input) {  
        var output = "";  
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;  
        var i = 0;  
        input = _utf8_encode(input);  
        while (i < input.length) {  
            chr1 = input.charCodeAt(i++);  
            chr2 = input.charCodeAt(i++);  
            chr3 = input.charCodeAt(i++);  
            enc1 = chr1 >> 2;  
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);  
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);  
            enc4 = chr3 & 63;  
            if (isNaN(chr2)) {  
                enc3 = enc4 = 64;  
            } else if (isNaN(chr3)) {  
                enc4 = 64;  
            }  
            output = output +  
            _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +  
            _keyStr.charAt(enc3) + _keyStr.charAt(enc4);  
        }  
        return output;  
    }  

    // public method for decoding  
    this.decode = function (input) {  
        var output = "";  
        var chr1, chr2, chr3;  
        var enc1, enc2, enc3, enc4;  
        var i = 0;  
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");  
        while (i < input.length) {  
            enc1 = _keyStr.indexOf(input.charAt(i++));  
            enc2 = _keyStr.indexOf(input.charAt(i++));  
            enc3 = _keyStr.indexOf(input.charAt(i++));  
            enc4 = _keyStr.indexOf(input.charAt(i++));  
            chr1 = (enc1 << 2) | (enc2 >> 4);  
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);  
            chr3 = ((enc3 & 3) << 6) | enc4;  
            output = output + String.fromCharCode(chr1);  
            if (enc3 != 64) {  
                output = output + String.fromCharCode(chr2);  
            }  
            if (enc4 != 64) {  
                output = output + String.fromCharCode(chr3);  
            }  
        }  
        output = _utf8_decode(output);  
        return output;  
    }  

    // private method for UTF-8 encoding  
    _utf8_encode = function (string) {  
        string = string.replace(/\r\n/g,"\n");  
        var utftext = "";  
        for (var n = 0; n < string.length; n++) {  
            var c = string.charCodeAt(n);  
            if (c < 128) {  
                utftext += String.fromCharCode(c);  
            } else if((c > 127) && (c < 2048)) {  
                utftext += String.fromCharCode((c >> 6) | 192);  
                utftext += String.fromCharCode((c & 63) | 128);  
            } else {  
                utftext += String.fromCharCode((c >> 12) | 224);  
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);  
                utftext += String.fromCharCode((c & 63) | 128);  
            }  

        }  
        return utftext;  
    }  

    // private method for UTF-8 decoding  
    _utf8_decode = function (utftext) {  
        var string = "";  
        var i = 0;  
        var c = c1 = c2 = 0;  
        while ( i < utftext.length ) {  
            c = utftext.charCodeAt(i);  
            if (c < 128) {  
                string += String.fromCharCode(c);  
                i++;  
            } else if((c > 191) && (c < 224)) {  
                c2 = utftext.charCodeAt(i+1);  
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));  
                i += 2;  
            } else {  
                c2 = utftext.charCodeAt(i+1);  
                c3 = utftext.charCodeAt(i+2);  
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));  
                i += 3;  
            }  
        }  
        return string;  
    }  
}
  </script>
</body>
</html>


第4步 上传成功后异步回调处理

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/10
 * Time: 15:19
 */
class sysoss_oss_aliyun_callback{
    /**
     * 前端oss上传成功后回调
     */
    public function ossCallback(){
        $authorizationBase64 = "";
        $pubKeyUrlBase64 = "";
        if (isset($_SERVER['HTTP_AUTHORIZATION']))
        {
            $authorizationBase64 = $_SERVER['HTTP_AUTHORIZATION'];
        }
        if (isset($_SERVER['HTTP_X_OSS_PUB_KEY_URL']))
        {
            $pubKeyUrlBase64 = $_SERVER['HTTP_X_OSS_PUB_KEY_URL'];
        }
        if ($authorizationBase64 == '' || $pubKeyUrlBase64 == '')
        {
            header("http/1.1 403 Forbidden");
            exit();
        }
        $authorization = base64_decode($authorizationBase64);
        $pubKeyUrl = base64_decode($pubKeyUrlBase64);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $pubKeyUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        $pubKey = curl_exec($ch);
        if ($pubKey == "")
        {
            exit();
        }
        $body = file_get_contents('php://input');
        $path = $_SERVER['REQUEST_URI'];
        $pos = strpos($path, '?');
        if ($pos === false)
        {
            $authStr = urldecode($path)."\n".$body;
        }
        else
        {
            $authStr = urldecode(substr($path, 0, $pos)).substr($path, $pos, strlen($path) - $pos)."\n".$body;
        }
        $ok = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5);
        if ($ok == 1)
        {
            header("Content-Type: application/json");
            $data = array(
                "success"=>true,
                'callbackdata'=>$_POST
            );
            $callbackinfo = $_POST;
            //网站业务处理
            echo json_encode($data);
        }
        else
        {
            exit();
        }
    }
}
  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
你可以使用 Element UI 和阿里云 OSS 来实现分片上传视频。首先,你需要在你的项目中引入 Element UI 组件库和阿里云 OSS 的 SDK。 然后,你可以使用 Element UI 中的上传组件来实现文件选择和上传的功能。在上传组件中,你可以设置一些参数来启用分片上传功能。例如,你可以设置 `chunkSize` 参数来指定每个分片的大小,以及 `chunkRetry` 参数来设置分片上传失败时的重试次数。 在上传过程中,你可以使用阿里云 OSS 的 SDK 来进行分片上传。你需要将视频文件切割成多个分片,并将每个分片上传阿里云 OSS 中的指定位置。可以使用 `oss.multipartUpload` 方法来实现分片上传功能。 具体的代码实现步骤如下: 1. 引入 Element UI 和阿里云 OSS 的 SDK: ```javascript import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import OSS from 'ali-oss'; ``` 2. 初始化阿里云 OSS 客户端: ```javascript const client = new OSS({ region: 'your_region', accessKeyId: 'your_access_key_id', accessKeySecret: 'your_access_key_secret', bucket: 'your_bucket_name' }); ``` 3. 在上传组件中设置分片上传参数: ```html <el-upload :action="your_upload_url" :on-success="handleSuccess" :chunk-size="your_chunk_size" :chunk-retry="your_chunk_retry" > <el-button slot="trigger">选择视频文件</el-button> </el-upload> ``` 4. 实现上传成功的回调函数: ```javascript handleSuccess(response, file, fileList) { // 在上传成功后,你可以根据需要进行后续处理,例如保存视频路径等操作 } ``` 5. 在回调函数中实现分片上传: ```javascript handleSuccess(response, file, fileList) { const { uploadId, name } = response.data; // 获取上传 ID 和文件名 const chunks = splitVideoIntoChunks(file); // 将视频文件切割成多个分片 const uploadPromises = chunks.map((chunk, index) => { return client.uploadPart(name, uploadId, index + 1, chunk); // 上传每个分片 }); Promise.all(uploadPromises) .then(results => { const etags = results.map(result => result.etag); return client.completeMultipartUpload(name, uploadId, etags); // 完成分片上传 }) .then(() => { console.log('分片上传完成'); }) .catch(error => { console.error('分片上传失败', error); }); } ``` 以上是一个简单的示例,你可以根据自己的需求进行适当调整。希望以上信息对你有所帮助!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值