码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2015-10-26 13:42:09      阅读:2333      评论:0      收藏:0      [点我收藏+]

标签:

  1. 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 = "{\n" +

                "    \"Version\": \"1\", \n" +

                "    \"Statement\": [\n" +

                "        {\n" +

                "            \"Action\": [\n" +

                "                \"oss:GetBucket\", \n" +  //此处表示对于myBucket的只能进行获取操作,若想进行更多操作将GetBucket改为*即可,否则会拒绝访问

                "                \"oss:GetObject\" \n" +   //此处表示对于myBucket下的文件夹project的只能进行获取操作,若想进行更多操作将GetObject改为*即可,否则会拒绝访问

                "            ], \n" +

                "            \"Resource\": [\n" +

                "                \"acs:oss:*:30150***706:myBucket\", \n" + //此处数字必须与RoleArn中的数字一直

                "                \"acs:oss:*:30150***706:myBucket/project/*\" \n" +

                "            ], \n" +

                "            \"Effect\": \"Allow\"\n" +

                "        }\n" +

                "    ]\n" +

                "}";

 

        // 此处必须为 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;
};

 

 

 

页面源码:

<!-- 文件列表 -->
<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="width:{{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>

 

最终效果图:

 技术分享

 

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

标签:

原文地址:http://www.cnblogs.com/anxiang/p/4910833.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!