阿里oss前端图片上传 - element

服务端生成签名,前端使用签名直接将图片上传到阿里oss。

服务端代码(Java)

参数说明:

String accessId = "<yourAccessKeyId>";   // 请填写您的AccessKeyId。
String accessKey = "<yourAccessKeySecret>"; // 请填写您的AccessKeySecret。
String endpoint = "oss-cn-hangzhou.aliyuncs.com"; // 请填写您的 endpoint。
String bucket = "bucket-name";          // 请填写您的 bucketname 。
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint

// callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
String callbackUrl = "http://88.88.88.88:8888";
String dir = "user-dir-prefix/"; // 用户上传文件时指定的前缀。

示例:

    @RequestMapping("/upload/img/param")
	public ResObject getUploadLink(String dir) {
	OSSClient client = new OSSClient(endpoint, accessId, accessKey);
    try{
			long expireTime = 30;
			long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
			Date expiration = new Date(expireEndTime);
			PolicyConditions policyConds = new PolicyConditions();
			policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
			if (StringUtils.hasText(dir)) {
				policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
			}
			String postPolicy = client.generatePostPolicy(expiration, policyConds);
			byte[] binaryData = postPolicy.getBytes("utf-8");
			String encodedPolicy = BinaryUtil.toBase64String(binaryData);
			String postSignature = client.calculatePostSignature(postPolicy);

			Map<String, String> respMap = new LinkedHashMap<String, String>();
			respMap.put("OSSAccessKeyId", accessId);
			respMap.put("policy", encodedPolicy);
			respMap.put("signature", postSignature);
			if (StringUtils.hasText(dir)) {
				respMap.put("dir", dir);
			}
			respMap.put("host", host);
			respMap.put("expire", String.valueOf(expireEndTime / 1000));
			return respMap;
	}catch (Exception e) {
			e.printStackTrace();
	}
	return Collections.EMPTY_MAP;
}

前端(js)

参数说明:

上传文件时附带的oss参数:

{
 'key' : 'abc/' + '${filename}',
 'policy': policyBase64,
 'OSSAccessKeyId': accessid,
 'success_action_status' : '200', //让服务端返回200,不然,默认会返回204
 'signature': signature,
};

说明:将服务端返回的参数与文件一起发给oss,文件追加在参数后面。

举例:如果项目中使用了上传组件,直接将签名数据传给组件即可,如,element上传组件:

 <el-upload
      :limit="3"
      :action="action"
      ref="picture"
      list-type="picture-card"
      :on-remove="handleRemove"
      :file-list="fileList"
      :on-change="handleChange"
      :before-upload="imgUploadRequest"
      :class="{NewsImageUpload:hideUpload}"
      :data="dataSign"
      accept="image/*"
     >

js代码:

async imgUploadRequest(file) {
   var that = this;
   var res = await loader.request(this.imgParamUrl, {});//请求服务端,获取上传签名。
   var data = res.data;
   if (data) {
    that.action = data.host;
    utils.copyProperty(data, that.dataSign, file);//自己包装的属性复制工具
    return true;
   }
   console.log("未能获取上凭证");
   return false;
  },

说明:在element上传组件的before-upload回调中从服务端获取签名数据,然后赋值给上传组件的:data属性。

自行构建上传请求示例

var formData = new FormData();

formData.append("key", "文件名");
formData.append("policy", policy); 
formData.append("OSSAccessKeyId", accessid); 
formData.append("success_action_status", 200); 
formData.append("signature", signature); 
formData.append("file", fileInputElement.files[0]);

说明:参数顺序不能随意,如果将file将在第一位,oss会提示找不到文件名,关于文件名一般每次上传时给个唯一的值,防止文件重名上传不成功。

var request = new XMLHttpRequest();
request.open("POST",host);//https://xieyonghui.com.oss-cn-beijing.aliyuncs.com/
request.send(formData);