这是基于Spring MVC实现的一个demo。
pom添加依赖包aliyun-sdk-oss
<dependencies>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.1</version>
</dependency>
</dependencies>
PostObjectPolicy
public class PostObjectPolicy {
private String accessId;
private String host;
private String dir;
private String policy;
private String expire;
private String signature;
//此处省略get,set方法
}
AliyunOSSClient 获取Policy
@Service
public class AliyunOSSClient {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.oss.accessKeySecret}")
private String accessKeySecret;
private OSSClient ossClient;
public AliyunOSSClient() {
}
@PostConstruct
void init() {
if(this.ossClient == null) {
this.ossClient = new OSSClient(this.endpoint, this.accessKeyId, this.accessKeySecret);
}
}
/**
* 获取Policy签名等信息
* @param bucket
* @param dir 存储在bucket的目录
* @param expiredSeconds 过期时间
* @return
*/
public PostObjectPolicy getPostObjectPolicy(String bucket,String dir,long expiredSeconds) {
long expireEndTime = System.currentTimeMillis() + expiredSeconds* 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = new byte[0];
try {
binaryData = postPolicy.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
PostObjectPolicy policy = new PostObjectPolicy();
policy.setAccessId(accessKeyId);
policy.setHost("https://" + bucket + "." + endpoint);
policy.setDir(dir);
policy.setExpire(String.valueOf(expireEndTime / 1000));
policy.setPolicy(encodedPolicy);
policy.setSignature(postSignature);
return policy;
}
}
Controller
@RestController
@RequestMapping("aliyun/oss")
public class AliyunOSSRest {
@Autowired
private AliyunOSSClient aliyunOSSClient ;
@Value("${aliyun.oss.buckeet}")
private String bucket;
@GetMapping("policy.json")
public PostObjectPolicy getPolicy() {
String dir = String.valueOf(System.currentTimeMillis());
return aliyunOSSClient .getPostObjectPolicy(bucket,dir,60);
}
}
前端(html和js)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
function upload () {
var file = $("#file").val();
if(file.length == 0) {
alert("请选择文件");
}
$.getJSON("getPolicy.json",function(policy) {
var filename = new Date().getTime() + getSuffix(file);
var formData = new FormData();
formData.append("file",$("#file")[0].files[0]);
//注意formData里append添加的键的大小写
formData.append('key', policy.dir + "/" + filename); //存储在oss的文件路径
formData.append('policy', policy.policy); //policy
formData.append('OSSAccessKeyId', policy.accessId); //accessKeyId
formData.append('success_action_status', "200"); //成功后返回的操作码
formData.append('Signature', policy.signature); //签名
var url = policy.host;
$.ajax({
url: url,
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
alert(returndata);
},
error: function (returndata) {
alert(returndata);
}
});
});
}
function getSuffix(fileName) {
var pos = fileName.lastIndexOf(".");
var suffix = '';
if(pos != -1) {
suffix = fileName.substring(pos);
}
return suffix;
}
</script>
<title>demo</title>
</head>
<body>
<form >
<input type="file" name="file" />
<a onclick="upload()">上传</a>
</form>
</body>
</html>
问题
跨域问题:
在阿里云选中oss上要设置跨域访问的bucket,在基础设置可以设置允许跨域访问的域名,如图: