zoukankan      html  css  js  c++  java
  • angulaijs中的ng-upload-file与阿里云oss服务的结合,实现在浏览器端上传文件到阿里云(速度可以达到1.5M)

    1. 2015-10-26
    2. angularjs结合aliyun浏览器端oos文件上传加临时身份验证例子
      1. 在服务端获取sts

    源码:

    public class StsServiceSample {
    
         // 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
    
        //<setting name="accessKeyId" value="H6JSh0Y****z2cGa" />
    
        //<setting name="ecretAccessKey" value="0joCPK6L1S0KLxC***3wulC7vG" />
    
          public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
    
          // 当前 STS API 版本
    
          public static final String STS_API_VERSION = "2015-04-01";
    
     
    
          static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret,
    
                                               String roleArn, String roleSessionName, String policy,
    
                                               ProtocolType protocolType) throws ClientException {
    
            try {
    
              // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
    
              IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
    
              DefaultAcsClient client = new DefaultAcsClient(profile);
    
     
    
              // 创建一个 AssumeRoleRequest 并设置请求参数
    
              final AssumeRoleRequest request = new AssumeRoleRequest();
    
              request.setVersion(STS_API_VERSION);
    
              request.setMethod(MethodType.POST);
    
              request.setProtocol(protocolType);
    
              request.setRoleArn(roleArn);
    
              request.setRoleSessionName(roleSessionName);
    
              request.setPolicy(policy);
    
     
    
              // 发起请求,并得到response
    
              final AssumeRoleResponse response = client.getAcsResponse(request);
    
     
    
              return response;
    
            } catch (ClientException e) {
    
              throw e;
    
            }
    
          }
    
          /**
    
         * @param args
    
         */
    
        /**
    
         * @param args
    
         */
    
        public static void main(String[] args) {
    
            // 只有 RAM用户(子账号)才能调用 AssumeRole 接口
    
            // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
    
            // 请首先在RAM控制台创建一个RAM用户,并为这个用户创建AccessKeys
    
            // 参考:https://docs.aliyun.com/#/pub/ram/ram-user-guide/user_group_management&create_user
    
            String accessKeyId = "G8dGVL***AwWWxX3";
    
            String accessKeySecret = "nmha7GAObJE1tF***RbqEB5TYU1ScK";
    
     
    
            // AssumeRole API 请求参数: RoleArn, RoleSessionName, Polciy, and DurationSeconds
    
            // 参考: https://docs.aliyun.com/#/pub/ram/sts-api-reference/actions&assume_role
    
     
    
            // RoleArn 需要在 RAM 控制台上获取
    
            // 参考: https://docs.aliyun.com/#/pub/ram/ram-user-guide/role&user-role
    
            String roleArn = "acs:ram::30150***706:role/lium";
    
     
    
            // RoleSessionName 是临时Token的会话名称,自己指定用于标识你的用户,主要用于审计,或者用于区分Token颁发给谁
    
            // 但是注意RoleSessionName的长度和规则,不要有空格,只能有'-' '_' 字母和数字等字符
    
            // 具体规则请参考API文档中的格式要求
    
            String roleSessionName = "lium";
    
     
    
            // 如何定制你的policy?
    
            // 参考: https://docs.aliyun.com/#/pub/ram/ram-user-guide/policy_reference&struct_def
    
            // OSS policy 例子: https://docs.aliyun.com/#/pub/oss/product-documentation/acl&policy-configure
    
            // OSS 授权相关问题的FAQ: https://docs.aliyun.com/#/pub/ram/faq/oss&basic
    
            String policy = "{
    " +
    
                    "    "Version": "1", 
    " +
    
                    "    "Statement": [
    " +
    
                    "        {
    " +
    
                    "            "Action": [
    " +
    
                    "                "oss:GetBucket", 
    " +  //此处表示对于myBucket的只能进行获取操作,若想进行更多操作将GetBucket改为*即可,否则会拒绝访问
    
                    "                "oss:GetObject" 
    " +   //此处表示对于myBucket下的文件夹project的只能进行获取操作,若想进行更多操作将GetObject改为*即可,否则会拒绝访问
    
                    "            ], 
    " +
    
                    "            "Resource": [
    " +
    
                    "                "acs:oss:*:30150***706:myBucket", 
    " + //此处数字必须与RoleArn中的数字一直
    
                    "                "acs:oss:*:30150***706:myBucket/project/*" 
    " +
    
                    "            ], 
    " +
    
                    "            "Effect": "Allow"
    " +
    
                    "        }
    " +
    
                    "    ]
    " +
    
                    "}";
    
     
    
            // 此处必须为 HTTPS
    
            ProtocolType protocolType = ProtocolType.HTTPS;
    
     
    
            try {
    
              final AssumeRoleResponse response = assumeRole(accessKeyId, accessKeySecret,
    
                      roleArn, roleSessionName, policy, protocolType);
    
     
    
              System.out.println("Expiration: " + response.getCredentials().getExpiration());
    
              System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
    
              System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
    
              System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
    
              System.out.println("RequestId: "+response.getRequestId());
    
     
    
     
    
            } catch (ClientException e) {
    
              System.out.println("Failed to get a token.");
    
              System.out.println("Error code: " + e.getErrCode());
    
              System.out.println("Error message: " + e.getErrMsg());
    
            }
    
     
    
          }
    
        }

    注意:这是maven工程需要在pom.xml文件中引入以下内容:

    <!-- 阿里云STS -->

                 <dependency>

                           <groupId>com.aliyun</groupId>

                           <artifactId>aliyun-java-sdk-sts</artifactId>

                           <version>2.1.6</version>

                 </dependency>

                 <dependency>

                           <groupId>com.aliyun</groupId>

                           <artifactId>aliyun-java-sdk-core</artifactId>

                           <version>2.1.7</version>

                 </dependency>

    最后将所需要的参数拼成json字符串,发送到前端即可,json例子如下:

    1. 前端js获取sts且添加工具包oss-js-upload.js和aliyun-sdk-js.js,详情请参考以下网址https://github.com/aliyun-UED/oss-js-uploadhttps://github.com/aliyun-UED/aliyun-sdk-js,请详细阅读README.md文件;

    源码:

    /**
    
     * 取得stsToken
    
     */
    
    $scope.getStsToken = function () {
    
        var qqslResource = $resource(httpUrl + 'oss/sts', {}, actions);
    
        qqslResource.get({}, function (data) {
    
            // 实例化上传对象
    
            $scope.ossUpload = new OssUpload({
    
                bucket: 'qqsl',
    
                // 根据你的 oss 实例所在地区选择填入
    
                endpoint: 'http://oss-cn-hangzhou.aliyuncs.com',
    
                // 如果文件大于 chunkSize 则分块上传, chunkSize 不能小于 100KB 即 102400
    
                chunkSize: 1048576,
    
                // 分块上传的并发数
    
                concurrency: 2,
    
                // 注意: 虽然使用 accessKeyId 和 secretAccessKey 可以进行上传, 但是存在泄露风险, 因此强烈建议使用下面的 STS token
    
                // 只有在确认不会出现泄露风险的情况下, 才使用 aliyunCredential
    
                stsToken: data
    
            });
    
        });
    
    };
    // 建立上传文件信息
    $scope.makeOptions = function (files, index) {
        var data = {
            // 必传参数, 需要上传的文件对象
            file: files[index],
            // 必传参数, 文件上传到 oss 后的名称, 包含路径
            key: "project/" + $scope.unit.treePath + "/" + files[index].name,
            // 上传失败后重试次数
            maxRetry: 2,
            // OSS支持4个 HTTP RFC2616(https://www.ietf.org/rfc/rfc2616.txt)协议规定的Header 字段:
            // Cache-Control、Expires、Content-Encoding、Content-Disposition。
            // 如果上传Object时设置了这些Header,则这个Object被下载时,相应的Header值会被自动设置成上传时的值
            // 可选参数
            headers: {
                'CacheControl': 'public',
                'Expires': '',
                'ContentEncoding': '',
                'ContentDisposition': '',
                // oss 支持的 header, 目前仅支持 x-oss-server-side-encryption
                'ServerSideEncryption': ''
            },
            // 文件上传失败后调用, 可选参数
            onerror: function (evt) {
                console.log(evt);
            },
            // 文件片上传事件
            onprogress: function (loaded, total, res) {
                $scope.onprogress(files, loaded, total, res);
            },
            // 文件上传成功调用, 可选参数
            oncomplete: function (res) {
                $scope.oncomplete(files, res);
            }
        };
        return data;
    };
    
     
    
     
    
    // 分片上传事件
    
    $scope.onprogress = function (files, loaded, total, res) {
    
        var fileName = res.key.substring(res.key.lastIndexOf("/") + 1);
    
        console.log(loaded, total, (loaded / total * 100).toFixed(1));
    
        var progress = (loaded / total * 100).toFixed(0);
    
        for (var i = 0; i < files.length; i++) {
    
            if (files[i].name == fileName) {
    
                files[i].progress = parseInt(progress);
    
                // 立即更新数据
    
                $scope.$apply();
    
                break;
    
            }
    
        }
    
    };
     
    
    // 文件上传成功事件
    
    $scope.oncomplete = function (files, res) {
    
        // 更新文件列表
    
        $scope.queryObjectFiles($scope.unit.id);
    
        if (res.Key) {
    
            // 大文件
    
            for (var i = 0; i < files.length; i++) {
    
                var fileName = res.Key.substring(res.Key.lastIndexOf("/") + 1);
    
                if (files[i].name == fileName) {
    
                    files.splice(i, 1);
    
                    break;
    
                }
    
            }
    
        }
    
        if (res.Key == undefined) {
    
            $scope.uploadSum++;
    
        }
    
        if ($scope.uploadSum >= files.length) {
    
            files.splice(0, files.length);
    
        }
    
    };
     
    
    // 多文件上传
    
    $scope.isdrop = false;
    
    $scope.uploadFiles = function (files) {
    
    
    
        if (files == undefined || files == null || files.length == 0) {
    
            $scope.isupload=true;
    
            $scope.setMsg('请拖拽要上传的文件!');
    
            return;
    
        }
    
        if (files.length > 10) {
    
            $scope.isupload=true;
    
            $scope.setMsg('最多一次性上传10个文件!');
    
            return;
    
        }
    
        var fileLength = files.length;
    
        $scope.uploadSum = 0;
    
        for (var i = 0; i < files.length; i++) {
    
            var name = files[i].name;
    
            console.log(name.substring(name.lastIndexOf(".") + 1));
    
            for(var w = 0;w < $scope.editGridOptions.data.length;w++){
    
                if($scope.editGridOptions.data[w].size==files[i].size&&
    
                    $scope.editGridOptions.data[w].name==files[i].name) {
    
                    files.splice(i, 1);
    
                }
    
            }
    
            // 小于36M的office文件上传到后台
    
            if (files[i].size < 36 * 1024 * 1024 &&
    
                $scope.toPdf.indexOf(name.substring(name.lastIndexOf(".") + 1)) != -1) {
    
                $scope.serverUpload($scope.unit.id, files[i]);
    
            }
    
            // 上传到阿里云oss
    
            $scope.ossUpload.upload($scope.makeOptions(files, i));
    
        }
    
    };
     
    
     
    
    /**
    
     * 自动检测上传的文件数目并删除重复文件
    
     * @param files
    
     */
    
    $scope.change = function(files){
    
        var result = [], hash = {},elem, i,name;
    
       if(files.length>10) {
    
           $scope.isupload = true;
    
           $scope.setMsg('最多一次性上传10个文件!');
    
           files.splice(10);
    
           console.log(files);
    
           return;
    
       }
    
        for(var i=0;i<files.length;i++){
    
            for(var j=i+1;j<files.length;){
    
                //后面的元素若和待比较的相同,则删除并计数;
    
                //删除后,后面的元素会自动提前,所以指针j不移动
    
                if(files[j].name==files[i].name&&files[j].size==files[i].size){
    
                    $scope.isupload=true;
    
                    name = files[i].name.length<10?files[i].name:files[i].name.substring(0,10)+"..";
    
                    $scope.setMsg('已删除重复文件:'+name);
    
                    files.splice(j,1);
    
                }else{
    
                    j++;
    
                }
    
           //不同,则指针移动
    
            }
    
        }
    
    };
    
    /**
    
     * 删除已拖拽的文件
    
     * @param name
    
     * @param file
    
     * @returns {*}
    
     */
    
    $scope.deleteFile = function (name, files) {
    
        console.log(name);
    
        for (var i = 0; i < files.length; i++) {
    
            if (files[i].name == name) {
    
                files.splice(i, 1)
    
            }
    
        }
    
        //$scope.isupload==false;
    
        $scope.change(files);
    
        console.log(files);
    
        return files;
    
    };

    在页面中使用ng-file-upload插件,此插件支持拖拽上传,累加拖拽,限制上传文件的格式以及大小,也有进度条插件。如果要显示进度条,必须要修改oss-file-upload源码才行。

    思路:页面用ng-file-upload插件,使用它提供的一些拖拽等功能,在js中将ng-file-upload的upload函数替换为oss中的upload对象即可,提供此对象所需要的参数即可。

    页面源码:

    <!-- 文件列表 -->
    
    <div class="clear col-lg-12" ng-if="unit.type=='DIRCTORY'">
    
        <div class="info-space">
    
            <p class="text-left lead">文件列表</p>
    
        </div>
    
        <div class="clear">
    
            <table ui-grid="editGridOptions" ui-grid-auto-resize class="ui-grid"
    
                   ng-style="getTableHeight()"></table>
    
        </div>
    
    
    
        <div class="clear info-space">
    
            <form name="fileForm">
    
                <!-- 上传 -->
    
                <div class="col-lg-6">拖拽文件:</div>
    
                <div class="col-lg-8">
    
                    <div ngf-drop ng-model="files" class="drop-box"
    
                         ngf-drag-over-class="dragover" ngf-multiple="true"
    
                         accept="image/*,application/*,.*" ngf-max-size="256MB" ngf-keep="true" ngf-change="change(files)"
    
                         ngf-pattern="'image/*,.*'">多文件拖拽上传
    
                    </div>
    
    
    
                    <div ngf-no-file-drop>此浏览器不支持文件拖拽上传功能</div>
    
                </div>
    
                <div class="clear info-space">
    
                    <div ng-show="msg.length>0&&isupload"
    
                         class="col-lg-5 col-lg-offset-3 text-center label-info edit-space">{{msg}}
    
                    </div>
    
                </div>
    
                <div class="col-lg-10">文件信息:
    
                    <ul style="list-style-type:none">
    
                        <li ng-repeat="f in files" style="height: 32px" class="col-lg-12">
    
                            <div class="col-lg-3" ng-show="f.progress >= 0" style="height: 32px">
    
                              <span class="progress">
    
                                <div style="{{f.progress}}%" ng-bind="f.progress + '%'">
    
                                </div>
    
                              </span>
    
                            </div>
    
                            <div class="col-lg-5">
    
                                &nbsp;&nbsp;{{f.name.length > 12 ? f.name.substring(0,12)+"...":f.name}}
    
                                </div>
    
                            <div class="col-lg-2">
    
                                &nbsp;&nbsp;{{f.size/1024>1024?(f.size/(1024*1024)).toFixed(2)+"MB":(f.size/1024).toFixed(2)+"kb"}}
    
                                </div>
    
                            <div class="col-lg-2">
    
                                <a href ng-click="deleteFile(f.name,files)"> 删除</a>
    
                            </div>
    
                        </li>
    
                    </ul>
    
                </div>
    
                <div class="col-lg-2">
    
                    <button ng-disabled="files.length>10?true:false"
    
                            ng-click="uploadFiles(files)" class="btn btn-primary">上传
    
                    </button>
    
                </div>
    
            </form>
    
        </div>
    
    
    
    </div>

    最终效果图:

     

  • 相关阅读:
    我查询的问题点
    更改hosts操作
    日常有用的网站
    加入到java后台开发
    知识点收藏
    Mac操作技巧
    设置自己的APP能打开文件(在其他应用中打开显示自己的应用)
    思维不要留在框里
    X RMAN Crosscheck后delete obsolete遇到RMAN-06091的解决
    X No standby redo logfiles created for thread 1
  • 原文地址:https://www.cnblogs.com/leinuo2016/p/4910833.html
Copyright © 2011-2022 走看看