阿里云OSS web端直传 不依赖官方pupload的插件

前言

做好了七牛云存储,又要换阿里云oss。。。哎。。。
记录一下过程。本次采用的是服务端生成签名。web端直传的方式。没设置回调

一、准备工作

浏览使用手册:

阿里云oss使用文档

几个关键的手册页面:

1、服务端签名后直传
2、php代码示例
3、PostObject API 说明

二、原理

1、用户发送上传Policy请求到应用服务器。
2、应用服务器返回上传Policy和签名给用户。
3、用户直接上传数据到OSS
(我是直接把签名生成到web页面)

三、开始开发

下载官方php demo。
在这里插入图片描述
打开demo中的get.php,如图。
可见,就是我们输入自己oss的一些配置信息,然后返回reponse数组。我理解为reponse这个数组就是返回的签名。
在这里插入图片描述
上面的配置信息都可以写入数据库中,然后从数据库读取。。
例如:
在这里插入图片描述

四、后端代码:

采用的是thinkphp5框架开发。
从数据库里面把配置读出来,然后复制上面demo的代码,返回reponse数组到前端。
这里是上传两个文件。一个到公共bucket,一个到私有bucket。所以。reponse数组会多了几个参数。

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();
    }

五、前端代码:

必须要设置好bucket的跨域规则。
在这里插入图片描述
开post权限

把reponse数组的参数渲染到模板中。

至于为什么这样写呢。。请细看阿里云官方的 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 部分:


            $.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生成浏览地址,或者下载地址就可以获取到我们想要的文件了。
先写成这样。。。

猜你喜欢

转载自www.cnblogs.com/fatcar/p/11346503.html