zoukankan      html  css  js  c++  java
  • layui OSS Web直传

    此次封装的oss直传 使用的是官网Browser.js和layui结合封装的插件。调用方式相对来说简单快捷

    1、html是一个上传按钮。这里注意一下两个id,

      id="upload-normal" :上传按钮的id。

      id="upload-normal-list":上传完图片(文件)展示的地方
      这两个是有规则的,必须为上传按钮的id 拼接上 -list
     
    .close_btn{ position: absolute; top:-7px!important; right: -7px!important; background: rgba(0,0,0,0.5); border-radius: 50%; width: 15px; height: 15px; border-radius: 50%; line-height: 15px;}
     1     <div class="layui-form-item">
     2         <label class="layui-form-label">图片</label>
     3         <div class="layui-input-block">
     4             <div class="layui-upload">
     5                 <button type="button" class="layui-btn layui-btn-sm" id="upload-normal">上传图片</button>
     6                 <div class="layui-upload-list" id="upload-normal-list" style="display: flex; flex-wrap: wrap;">
     7                 </div>
     8             </div>
     9         </div>
    10     </div>

    2、js

         首先去官网下载sdk并按照文档引入js

      官方链接:https://helpcdn.aliyun.com/document_detail/64041.html?spm=a2c4g.11186623.6.1218.4d8b23f2hNmYrh

      封装后的js(注意最好使用layui2.6.5及以上版本 因为他这个版本修复了(这个版本之前的自己去修改下layui.js)

    • [修复] form 组件的 name="arr[]" 在元素动态插入后出现序号异常的问题

      

    <script src="src/lib/extend/aliyun-oss-sdk.min.js"></script>
      1 layui.extend({}).define(['layer', 'upload', 'setter', 'jquery'], function (exports) {
      2     var $ = layui.$,
      3         layer = layui.layer,
      4         setter = layui.setter,
      5         upload = layui.upload,
      6         layer = layui.layer;
      7 
      8     var Class = function (options) {
      9         var that = this;
     10         that.options = options;
     11         that.init();
     12     };
     13 
     14     Class.prototype.init = function () {
     15         var that = this,
     16             options = that.options;
     17 
     18         if (!that.strIsNull(that.options.fileType)) {
     19             fileType = that.options.fileType;
     20         } else {
     21             fileType = 'file';
     22         }
     23 
     24         if (typeof that.options.uploadRenderData != 'undefined') {
     25             uploadRenderData = that.options.uploadRenderData;
     26         } else {
     27             uploadRenderData = {};
     28         }
     29 
     30 
     31 
     32         var loadingIndex;
     33         var uploadRender = upload.render($.extend({
     34             elem: that.options.elm,
     35             accept: fileType,
     36             multiple: that.options.multiple,
     37             auto: false,
     38             number: that.options.number ? that.options.number : 0,
     39             choose: function (obj) {
     40 
     41                 uploadRender.config.elem.next()[0].value = '';
     42                 let d = new Date();
     43                 var year = d.getFullYear();
     44                 var month = d.getMonth() + 1;
     45                 var day = d.getDate();
     46                 var folder = that.options.folder ? that.options.folder : 'default';
     47                 var save_path = folder + '/' + year + '/' + month + day + '/';
     48                 let admin_info = layui.data(setter.tableName).admin;
     49 
     50                 let curFiles = obj.pushFile();
     51                 var file_length = Object.keys(curFiles).length;
     52 
     53                 //loading层
     54                 loadingIndex = layer.load(2, { //icon支持传入0-2
     55                     shade: [0.5, '#000'], //0.5透明度的灰色背景
     56                     content: '上传中...',
     57                     success: function (layero) {
     58                         layero.find('.layui-layer-content').css({
     59                             'padding-top': '39px',
     60                             'width': '60px'
     61                         });
     62                     }
     63                 });
     64 
     65                 obj.preview(function (index, file, result1) {
     66                     var size = file.size;
     67                     var file_name = file.name;
     68                     var file_type = file.type;
     69 
     70                     let index1 = file_name.lastIndexOf('.');
     71                     let file_ext = file_name.substring(index1);
     72 
     73                     var code = "";
     74                     for (var i = 0; i < 6; i++) {
     75                         var radom = Math.floor(Math.random() * 10);
     76                         code += radom;
     77                     }
     78                     var save_name = d.getTime() + code + file_ext;
     79                     var storeAs = save_path + save_name;
     80 
     81                     var max_size = that.options.max_size ? that.options.max_size : 100 * 1024 * 1024;
     82                     if (size > max_size) {
     83                         layer.msg('上传的文件大小超出限制', { icon: 5 });
     84                         layer.close(loadingIndex);
     85                         return false;
     86                     }
     87 
     88                     //组装传输的参数,上传后阿里云会带着这些参数访问回掉方法
     89                     let data_param = {
     90                         uid: admin_info.uid,        //后台操作uid
     91                         filename: file_name,        //文件名称
     92                         filesize: size,            //文件大小
     93                         file_type: file_type,        //文件类型
     94                         file_ext: file_ext,        //文件文件后缀
     95                         save_name: save_name,        //阿里云的保存名称
     96                         save_path: save_path,        //阿里云的保存路径
     97                         all_path: storeAs,            //阿里云全路径
     98                     };
     99 
    100                     //上传
    101                     OSS.urllib.request('获取你签名的后台地址', { method: 'GET'}, (err, response) => {
    102 
    103 
    104                         if (err) {
    105                             return alert(err);
    106                         }
    107                         try {
    108                             result = JSON.parse(response);
    109                         } catch (e) {
    110                             return alert('parse sts response info error: ' + e.message);
    111                         }
    112                         let client = new OSS({
    113                             accessKeyId: result.data.AccessKeyId,
    114                             accessKeySecret: result.data.AccessKeySecret,
    115                             stsToken: result.data.SecurityToken,
    116                             // region表示您申请OSS服务所在的地域,例如oss-cn-hangzhou。
    117                             region: '',
    118                             bucket: ''
    119                         });
    120 
    121                         //记录断点
    122                         if (!tempCheckpoint) {
    123                             var tempCheckpoint;
    124                         }
    125                         // storeAs可以自定义为文件名(例如file.txt)或目录(例如abc/test/file.txt)的形式,实现将文件上传至当前Bucket或Bucket下的指定目录。
    126                         // file可以自定义为File对象、Blob数据以及OSS Buffer。
    127                         client.multipartUpload(storeAs, file, {
    128                             progress: async function (p, checkpoint) {
    129                                 tempCheckpoint = checkpoint;
    130                             },
    131                             parallel: that.options.parallel ? that.options.parallel : 1,
    132                             partSize: that.options.partSize ? that.options.partSize : 102400,
    133                             checkpoint: tempCheckpoint,
    134                             callback: {
    135                                 url: setter.callback_api_url + '/admin/CommonOss/callbackFile',
    136                                 body: 'bucket=${bucket}&object=${object}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&param=${x:param}',
    137                                 contentType: 'application/x-www-form-urlencoded',
    138                                 customValue: {
    139                                     'param': JSON.stringify(data_param)
    140                                 }
    141                             },
    142                         }).then(function (result) {
    143 
    144                             var list_id = that.options.elm + '-list';
    145 
    146                             var orgin_res = result.data.data;
    147                             if (!orgin_res) {
    148                                 layer.msg('上传失败', { icon: 5, time: 1500 });
    149                                 layer.close(loadingIndex);
    150                             }
    151 
    152                             var img_type = '';
    153                             var image_type = orgin_res.file_type;
    154                             img_type = image_type.split('/')[0];
    155 
    156                             html = '';
    157                             html1 = '';
    158                             attach_name = that.options.attach_name ? that.options.attach_name : '';
    159                             if (that.options.multiple) {
    160                                 html1 += '<input type="hidden" name="' + attach_name + '[]" value="' + orgin_res.attach_id + '">';
    161                             } else {
    162                                 html1 += '<input type="hidden" name="' + attach_name + '" value="' + orgin_res.attach_id + '">'
    163                             }
    164 
    165 
    166                             if (img_type == 'image') {
    167 
    168                                 html += '<div style="position:relative;  100px; margin:0 10px 10px 0;">' +
    169                                     '<img src="' + orgin_res.full_path + '" alt="" width="100"  class="view_btn">' +
    170                                     '<i class="layui-icon close_btn close_blog" close="">ဆ</i>' + html1 +
    171                                     '</div>';
    172 
    173                             } else if (img_type == 'video') {
    174 
    175                                 html += '<div style="position:relative;  150px; margin:0 10px 10px 0;">' +
    176                                     '<video src="' + orgin_res.full_path + '" width="150" controls="controls"></video>' +
    177                                     '<i class="layui-icon close_btn close_blog" close="">ဆ</i>' + html1 +
    178                                     '</div>';
    179                             } else {
    180 
    181                                 html += '<div>' +
    182                                     '<a href="' + orgin_res.full_path + '">' + orgin_res.filename + '</a>' +
    183                                     '<span class="close_blog" style="margin-left: 15px;color:red; cursor:pointer">删除</span>' + html1 +
    184                                     '</div>';
    185                             }
    186 
    187 
    188 
    189                             if (that.options.multiple) {
    190                                 $(list_id).append(html);
    191                             } else {
    192                                 $(list_id).html(html);
    193                             }
    194 
    195                             if (Object.keys(curFiles).length > 0) {
    196                                 delete curFiles[index]
    197                                 file_length--
    198                                 if (file_length == 0) {
    199                                     layer.close(loadingIndex);
    200                                 }
    201                             }
    202 
    203 
    204 
    205                         }).catch(function (err) {
    206                             console.log(err);
    207                             layer.msg('上传失败', { icon: 5, time: 1500 });
    208                             layer.close(loadingIndex);
    209                         });
    210                     });
    211 
    212                 });
    213             }
    214 
    215         }), uploadRenderData);
    216 
    217     };
    218 
    219 
    220 
    221     Class.prototype.strIsNull = function (str) {
    222         if (typeof str == "undefined" || str == null || str == "")
    223             return true;
    224         else
    225             return false;
    226     };
    227 
    228     var aliossUpload = {
    229         render: function (options) {
    230             var inst = new Class(options);
    231             return inst;
    232         }
    233     };
    234 
    235 
    236     $(document).on('click', ".close_blog", function () {
    237         $(this).parent().remove();
    238     });
    239 
    240     $(document).on('click', ".view_btn", function () {
    241         var attach_url = $(this)[0].src
    242         window.open(attach_url);
    243     });
    244 
    245     exports('aliossUpload', aliossUpload);
    246 
    247 
    248 })

    3、调用方式

      

     1 layui.define(['jquery','upload', 'form', 'aliossUpload'], function (exports) {
     2         var $ = layui.jquery
     3             , aliossUpload = layui.aliossUpload
     4 
     5         aliossUpload.render({
     6             elm: '#upload-normal',  //上传按钮id
     7             fileType: 'images',        //限制上传类型
     8             multiple: false,        //单图or 多图
     9             attach_name:'image',    //上传input的name值
    10             folder: 'slide',        //上传oss目录
    11             number: 1               //设置同时可上传的文件数量,一般配合 multiple 参数出现。0(即不限制)
    12         });
    13 
    14     exports('slide_upload', {})
    15 });

    以上是前端上传的代码及调用方式。接下来稍微简单说一下后代返回的签名及上传回调

       你可以使用官网php的sdk,也可以用composer安装

     我使用的是composer

       composer require aliyunsts/aliyun-sts

      1、 获取签名代码:

        public function sts()
        {
            $config = config("aliyun.oss_sts");
            $AccessKeyID = $config['AccessKeyID'];
            $AccessKeySecret = $config['AccessKeySecret'];
            $roleArn = $config['RoleArn'];
            $RoleSessionName = $config['RoleSessionName'];
            $tokenExpire = $config['DurationSeconds'];
            $policy = $this->_getPolicy();
    
            $iClientProfile = DefaultProfile::getProfile("cn-beijing", $AccessKeyID, $AccessKeySecret);
            $client = new DefaultAcsClient($iClientProfile);
            $request = new AssumeRoleRequest();
            $request->setRoleSessionName($RoleSessionName);
            $request->setRoleArn($roleArn);
            $request->setPolicy($policy);
            $request->setDurationSeconds($tokenExpire);
            $response = $client->doAction($request);
    
            $rows = array();
            $body = $response->getBody();
            $content = json_decode($body);
            $rows['status'] = $response->getStatus();
            if ($response->getStatus() == 200) {
                $rows['AccessKeyId'] = $content->Credentials->AccessKeyId;
                $rows['AccessKeySecret'] = $content->Credentials->AccessKeySecret;
                $rows['Expiration'] = $content->Credentials->Expiration;
                $rows['SecurityToken'] = $content->Credentials->SecurityToken;
                return $this->jsonSuccess($rows);
            }
            return $this->jsonError($content->Message);
        }

     2、aliyun文件回调

    public function callbackFile()
        {
            $is_success = false;
            try {
                // 1.获取OSS的签名header和公钥url header
                $authorizationBase64 = "";
                $pubKeyUrlBase64 = "";
                /*
                 * 注意:如果要使用HTTP_AUTHORIZATION头,你需要先在apache或者nginx中设置rewrite,以apache为例,修改
                 * 配置文件/etc/httpd/conf/httpd.conf(以你的apache安装路径为准),在DirectoryIndex index.php这行下面增加以下两行
                  RewriteEngine On
                  RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
                 * */
                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();
                }
    
                // 2.获取OSS的签名
                $authorization = base64_decode($authorizationBase64);
    
                // 3.获取公钥
                $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 == "") {
                    //header("http/1.1 403 Forbidden");
                    exit();
                }
    
                // 4.获取回调body
                $body = file_get_contents('php://input');
    
                trace($body, __METHOD__);
    
                // 5.拼接待签名字符串
                $path = $_SERVER['REQUEST_URI'];
                $pos = strpos($path, '?');
                if ($pos === false) {
                    $authStr = urldecode($path) . "
    " . $body;
                } else {
                    $authStr = urldecode(substr($path, 0, $pos)) . substr($path, $pos, strlen($path) - $pos) . "
    " . $body;
                }
    
                // 6.验证签名
                $ok = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5);
                if (empty($ok)) {
                    throw new Exception('验证签名失败');
                }
           
           // 7.处理相关业务


    $is_success = true; } catch (Exception $e) { $body = file_get_contents('php://input'); $res = 'oss callback error' . $e->getMessage() . $e->getLine(); Log::record($res . ",data:" . json_encode($body), 'warning'); } if ($is_success) { return $this->jsonSuccess($res); } else { return $this->jsonError($res); } }

      sts策略

    private function _getPolicy(){
        //你的sts策略
    }

    可能有有些还不够完善,有啥问题再继续更新修改吧!!!!!!

  • 相关阅读:
    VMware安装Centos7超详细过程(图文)
    linux中yum与rpm区别
    xshell连接本地虚拟机中的centos
    虚拟主机安装 CentOS 8 出现 “ pane is dead ” 故障解决方案
    python字符串前面添加(u,r,b)的功能
    from . import XXX
    我关注的博客
    并发与并行的区别
    GSAP学习(二)——载入
    GSAP学习(一)——什么是GSAP
  • 原文地址:https://www.cnblogs.com/widgetbox/p/14931535.html
Copyright © 2011-2022 走看看