• netcore3.1增加阿里云OSS云存储服务


    问题描述:由于最近的项目访问量有点大,决定部署到两台服务器,做负载的同时问题也发现了,之前的程序附件上传是上传到程序根目录的,由于做了负载,网站访问的资源就得看运气了,多刷几次才能访问的到,于是乎干脆把资源文件都放到oss上面。

    解决方案:先说一下整体思路,前台是jquery的,页面加载获取osstoken,有效期是10分钟,获取时候传个参数,后台根据参数判断文件存放位置,返回加密的token,前台拿到token就能给阿里云oss上传附件了。阿里云文档还是比较健全的,找了几个开源的源码关于oss上传,照猫画虎的来了一遍,慢慢摸索出了一些经验,首先阿里有oss的sdk包(Aliyun.OSS.SDK.NetCore,当前是2.9.1版本),引用到项目中,添加服务类

    public static class ALiOSSHelper
        {
            private static readonly ILog FileLog = LogManager.GetLogger("NETCoreRepository", typeof(ALiOSSHelper));
    
            private const string AccessKeyID = "XXX";
            private const string AccessKeySecret = "XXX";
            private const string Host = "http://XXX.oss-cn-beijing.aliyuncs.com";
            private const string BucketName = "XXX";
    
            public static ALiOSSTokenModel GetToken(int fileType)
            {
                var TargetDir = "FruitsCMS";
                switch (fileType)
                {
                    //资讯图片
                    case 1:
                        TargetDir += "/NewsPic";
                        break;
                    //轮播图
                    case 2:
                        TargetDir += "/ScrollPic";
                        break;
                    //友情链接Logo
                    case 3:
                        TargetDir += "/LinkPic";
                        break;
                    default:
                        TargetDir += "/UploadImage";
                        break;
                }
                OssClient client = new OssClient(Host, AccessKeyID, AccessKeySecret);
                //密钥过期时间为10分钟
                var expiration = DateTime.Now.AddMinutes(10);
                var policyConds = new PolicyConditions();
                policyConds.AddConditionItem("bucket", BucketName);
                policyConds.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, TargetDir);
                policyConds.AddConditionItem(MatchMode.StartWith, "x-oss-meta-tag", "dummy_etag");
                //限制传输文件大小10M
                policyConds.AddConditionItem(PolicyConditions.CondContentLengthRange, 1, 10240000);
                var postPolicy = client.GeneratePostPolicy(expiration, policyConds);
                var encPolicy = Convert.ToBase64String(Encoding.UTF8.GetBytes(postPolicy));
                var signature = ComputeSignature(AccessKeySecret, encPolicy);
                var tempRet = new ALiOSSTokenModel
                {
                    key = TargetDir,
                    bucket = BucketName,
                    OSSAccessKeyId = AccessKeyID,
                    policy = encPolicy,
                    Signature = signature
                };
                FileLog.Info("返回阿里云OSSToken信息:" + tempRet.ToJson());
                return tempRet;
            }
    
            private static string ComputeSignature(string key, string data)
            {
                using (var algorithm = KeyedHashAlgorithm.Create("HmacSHA1".ToUpperInvariant()))
                {
                    algorithm.Key = Encoding.UTF8.GetBytes(key.ToCharArray());
                    return Convert.ToBase64String(
                        algorithm.ComputeHash(Encoding.UTF8.GetBytes(data.ToCharArray())));
                }
            }
        }
    返回给前台的对象模型
        public class ALiOSSTokenModel
        {
            public string key { get; set; }
    
            public string bucket { get; set; }
    
            public string OSSAccessKeyId { get; set; }
    
            public string policy { get; set; }
    
            public string Signature { get; set; }
        }

    最小改动原则,在页面底部增加一个单独的上传文件隐藏form,接口返回模型赋值即可

    <form id="form2" action="http://XXX-cn-beijing.aliyuncs.com" method="POST" enctype="multipart/form-data">
        <input type="hidden" id="key" name="key" />
        <input type="hidden" id="bucket" name="bucket" />
        <input type="hidden" id="x-oss-meta-tag" name="x-oss-meta-tag" value="dummy_etag_xxx" />
        <input type="hidden" id="OSSAccessKeyId" name="OSSAccessKeyId" />
        <input type="hidden" id="policy" name="policy" />
        <input type="hidden" id="Signature" name="Signature" />
        <input type="file" id="file" name="file" accept="image/*" style="display:none;">
    </form>
        function loadOssTokenInfo() {
            $.ajax({
                url: "/Upload/GetOSSToken?fileType=3",
                dataType: "json",
                async: false,
                success: function (data) {
                    $("#form2").formSerialize(data);
                }
            });
        }
        function initControl() {
            $("#Status").bindSelect();
            $("#file").change(function () {
                var f = document.getElementById("file").files;
                if (f.length == 0) {
                    $("#PicAddr").val("");
                } else {
                    var tempFile = $("#file").val();
                    var tempFilePath = $("#key").val();
                    var tempNewFile = tempFilePath + "/" + random_string() + get_suffix(tempFile);
                    $("#key").val(tempNewFile);
                    $('#form2').ajaxSubmit({
                        dataType: 'json',
                        success: function () {
                            $("#PicAddr").val("https://XXX/" + tempNewFile);
                        },
                        error: function () {
                            $.modalAlert("上传失败,请稍候重试", "error");
                        }
                    });
                }
            });
            this.loadOssTokenInfo();
        }

    代码顺序有点凌乱,大概就是这样的思路,还遇到一个问题就是编辑器里的图片上传,我用的tinymce,在里面的upload插件里照住这个改一通,有个要注意的就是form里的id是需要设置不一样的,方便赋值与取值,但不影响表单提交的,去oss后台设置一些图片处理的方法,比如裁切、水印等,前台调用直接多加个后缀就ok了,大功告成,哦了。

  • 相关阅读:
    springcloud 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    java 整合redis缓存 SSM 后台框架 rest接口 shiro druid maven bootstrap html5
    继承
    封装
    对象的生命周期
    类与对象
    如何理解类?
    面向过程
    jdk1.8新特性
    git使用指南
  • 原文地址:https://www.cnblogs.com/wangbg/p/12550036.html
Copyright © 2020-2023  润新知