阿里云OSS前端web直传 .net C# .net core

背景

阿里云oss使用web直接上传的有两种方式

1. 是通过阿里云自己的js sdk上传, 但是这种上传方式有个比较麻烦的地方, 获取授权的时候配置会比较麻烦

2. 通过form表单提交或者post提交, 这种配置会比较简单一点

无论是哪种大致的思路都是先在后台通过接口获取一些参数, 然后在web端发起请求的带入. 由于这些参数的获取包含了授权签名等一系列敏感操作, 所以不建议直接在前端操作, 风险比较大

实现

阿里云后台配置允许跨域

在阿里云oss后台配置允许post跨域

后端组织前端所需的参数

1. 先通过nuget安装阿里云SDK : Aliyun.OSS.SDK, .net core 请安装 Aliyun.OSS.SDK.NetCore

 2. 编写接口

        /// <summary>
        /// 获取阿里云oss 签名信息
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns></returns>
        public Dictionary<string, string> GetAliyunOssSignPlicy(string fileName)
        {
            var accessKeyId = "你的Key Id";
            var accessKeySecret ="你的 Key Secret";
            var bucketName = "你的 BucketName";
            var endpoint = "你的Endpoint";
            var dir = DateTime.Now.ToString("yyyyMMdd") + "/";
            // 构造OssClient实例。 endpoint 格式:https://oss-cn-beijing.aliyuncs.com
            var ossClient = new OssClient("https://" + endpoint, accessKeyId, accessKeySecret);
            var config = new PolicyConditions();
            config.AddConditionItem(PolicyConditions.CondContentLengthRange, 1, 1024L * 1024 * 1024 * 5);// 文件大小范围:单位byte
            config.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, dir);
            var expire = DateTimeOffset.Now.AddMinutes(30);// 过期时间
            // 生成 Policy,并进行 Base64 编码
            var policy = ossClient.GeneratePostPolicy(expire.LocalDateTime, config);
            var policyBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(policy));

            // 计算签名
            var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(accessKeySecret));
            var bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(policyBase64));
            var sign = Convert.ToBase64String(bytes);
            // 将签名和回调的内容,返回给前端
            var host = $"https://{bucketName}.{endpoint}";
            var key = $"{dir}{Guid.NewGuid()}_{fileName}";
            var fullUrl = $"https://{bucketName}.{endpoint}/{key}";
            var rt = new Dictionary<string, string>
            {
                { "OSSAccessKeyId",accessKeyId},
                { "Host",host },
                { "key",key},
                { "policy",policyBase64},
                { "Signature",sign},
                { "success_action_status","200"},
                { "fullUrl",fullUrl }
            };
            return rt;
        }

3. 前端调用

先通过文件名获取到上传所需的参数, 然后通过post上传

<input id="uploadfile" type="file" />
  <script type="text/javascript">
    document.getElementById("uploadfile").onchange = function () {
      var inputfile = document.getElementById("uploadfile");
      //判断是否已经选中文件
      if (inputfile.files.length == 0) {
        alert("请选择你想要上传的附件!");
        return;
      }
      $.ajax({
        url: '../api/file/GetAliyunOssSignPlicy',
        type: 'post',
        data: { fileName: inputfile.files[0].name },
        success: function (res) {
          var formData = new FormData();
          formData.append("OSSAccessKeyId", res.OSSAccessKeyId);
          formData.append("key", res.key);
          formData.append("policy", res.policy);
          formData.append("Signature", res.Signature);
          formData.append(
            "success_action_status",
            res.success_action_status
          );
          formData.append("file", fl[0]);
          $.ajax({
            url: res.host,
            type: 'POST',
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            success: function (upres) {
              console.log('success', upres);
            },
            error: function (uperr) {
              console.log('error', uperr);
            }
          });
        },
        error: function (err) {
          console.log('error', err);
        }
      });
    }
  </script>

 

posted @ 2022-11-01 14:34  范斯  阅读(1307)  评论(0编辑  收藏  举报