服务端签名后前端直接上传图片到阿里云OSS示例(Java)

这是基于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 id="uploadForm">
	<input type="file" id="file" name="file" />
	<a onclick="upload()">上传</a>
</form>
</body>
</html>

问题

跨域问题:

在阿里云选中oss上要设置跨域访问的bucket,在基础设置可以设置允许跨域访问的域名,如图:


版权声明:著作权归作者所有。

一直报400,后台传到前台的数据是对的
你好 一直报跨域的问题 请问需要怎么配置啊???
@Victor 可以在阿里云的oss上设置允许跨域的域名,更新了文章
@红桃 js代码有一个地方写错。
原来是form.append("file",$("#file")[0].files[0]);
已更正为formData.append("file",$("#file")[0].files[0]);

你看下是不是这个原因导致报400。400的原因是传给阿里云的参数有误
相关推荐

Laravel 5的Intervention Image上传处理图片内存设置

在PHP处理图片是一个耗内存的任务。如果没有设置合适的内容,使用Intervention Image可能会导致异常。在php.ini有三个参数需要设置:memory_limit设置内存大小,可以设置为256M。3000 x 2000 像素的图片缩写为300 x 200像素需要32M。upload_max_filesize现在上传图片的大小

React Router 4 表单提交后重定向示例

表单设置fireRedirect为发起从定向的标记,当表单提交后,更新它的值为fireRedirect=true。当fireRedirect为true时,重定向到原来的页面。import React, { Component } from 'react' import { Redirect } from 'react-router' export default class MyForm

添加已有项目到远程服务器的Git仓库

按一下步骤添加已有项目到远程服务器的git仓库:1、在项目的根目录下初始化为git本地仓库git init 2、添加项目的所有文件到本地仓库,在项目的根目录执行:git add . 3、提交已添加的文件到本地仓库:git commit -m 'First commit' -m:用于添加提交日志4、添加远程git仓库获取项目在远程

CentOS 7更新为阿里云yum源

进入yum源的目录centos 7yum源目录为/etc/yum.repos.d$cd /etc/yum.repos.d 备份yum源在更新centos 7的yum源前先备份。$ sudo cp CentOS-Base.repo backup/ 如果没有bakcup目录先创建。下载阿里云yum源阿里云yum源列表:http://

解决升级到iOS 11后UIBarButtonItem图片变形的问题

在iOS 10使用UIBarUbttonItem图片显示正常,升级到iOS 11后,图片拉伸变形。这个原因是从iOS 11开始,UIBarButtonItem使用了autolayout 而不是frame。解决方法是,对UIBarButtonItem里的图片按钮添加约束。例如(swift):button.widthAnchor.constraint(equalToCon