OSS前后端分离式上传文件,OSS前端直传

您所在的位置:网站首页 微信可以借钱吗怎么借5000元 OSS前后端分离式上传文件,OSS前端直传

OSS前后端分离式上传文件,OSS前端直传

2024-05-29 20:24| 来源: 网络整理| 查看: 265

背景

以前我们一直采用: 后端转传 的方式进行文件上传 发现效率很低 且 后端服务器压力较大 现在我们优化成: 前端直传 后端提供token令牌 前端拿到令牌直接访问OSS上传文件效率提高了 且服务器压力也小了

准备工作

1:登录阿里云控制台创建RAM用户 在这里插入图片描述 在这里插入图片描述 及时截图或者复制 AccessKey ID 和 AccessKey Secret 这两项是OSS权限 在这里插入图片描述

这个STS角色访问权限 需要通过这个权限去获取token

在这里插入图片描述 创建角色 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

创建OSS存储桶

在这里插入图片描述 在这里插入图片描述 取名选择区域按提示完成创建 在这里插入图片描述

开放跨域请求

在这里插入图片描述 在这里插入图片描述

准备工作完毕

建个Spring Boot项目

引入依赖

com.aliyun.oss aliyun-sdk-oss 3.10.2 javax.xml.bind jaxb-api 2.3.1 javax.activation activation 1.1.1 org.glassfish.jaxb jaxb-runtime 2.3.3 写个接口应该难不倒你 @RestController @RequestMapping("/manager/auth") public class AuthController { @Autowired private OssService ossService; @GetMapping(value = "/oss/token") //这里的R是我自己封装的统一返回对象 你也可以直接返回JSON啥的 public R ossToken() { return R.data(ossService.token()); } } # 文件上传 OSS: # 区域 endpoint: "https://oss-cn-xxxxx.aliyuncs.com" # 密钥 accessKeyId: "xxxxxxxxxxxxxxxxxxxxxxxx" accessKeySecret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # roleArn roleArn: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 桶 bucketName: "xxxxxxxxx" regionId: "cn-shanghai" version: "2015-04-01" @Data @Configuration public class OSSParam { @Value("${OSS.endpoint}") private String endpoint; @Value("${OSS.accessKeyId}") private String accessKeyId; @Value("${OSS.accessKeySecret}") private String accessKeySecret; @Value("${OSS.roleArn}") private String roleArn; @Value("${OSS.bucketName}") private String bucketName; @Value("${OSS.regionId}") private String regionId; @Value("${OSS.version}") private String version; } public interface OssService { /** * 获取上传文件的token * @return */ AssumeRoleResponse token(); /** * 批量获取图片连接 * * @param filePathList * @return */ Map getUrlBatch(Collection filePathList); } @Service public class OssServiceImpl implements OssService { /** * 自定义的配置参数的类 */ @Autowired private OSSParam ossParam; @Override public AssumeRoleResponse token() { //随便写 参考下列格式即可 不要有特殊符号 String roleSessionName = "session_1001"; //执行角色授权 IClientProfile profile = DefaultProfile.getProfile( //cn-hangzhou 或者 cn-beijing 或者 cn-shanghai 这几个节点都可以 其他的好像不行 ossParam.getRegionId(), //开通账号时下发的两个参数 ossParam.getAccessKeyId(), ossParam.getAccessKeySecret() ); DefaultAcsClient client = new DefaultAcsClient(profile); final AssumeRoleRequest request = new AssumeRoleRequest(); //version 这里是固定的 2015-04-01 request.setVersion(ossParam.getVersion()); //开通角色时 角色信息里的 arn 属性 request.setRoleArn(ossParam.getRoleArn()); request.setRoleSessionName(roleSessionName); //临时授权有效时间,从 900 到 3600 秒 测试的时候建议写时间给长一点,免得报错都不知道为啥 request.setDurationSeconds(900L); try { final AssumeRoleResponse response = client.getAcsResponse(request); return response; } catch (ClientException e) { e.printStackTrace(); return null; } } /** * 文件临时访问 URL 获取 * * @param filePathList 后端存储的文件路径 * 例如 : web/img/abc.jpg * 其实就是你存储桶里面的文件夹路径 * 注意最前面不要带斜杠 例如这样 /web/img/abc.jpg 不要问我为什么 自己去试试就知道了 * @return 文件夹链接的 key : value 集合 调用方可以直接通过 map.get(filePath) 直接获取对应的链接 */ @Override public Map getUrlBatch(Collection filePathList) { //这里 等于 Map resultMap = new HashMap(); 只是我引用了工具包看起来舒服一点 Map resultMap = Maps.newHashMap(); if (CollectionUtils.isEmpty(filePathList)) { return resultMap; } //这个token可以用redis存起来过期了再重新生成,效率会高一点 //过期时间保持一致 或者redis缓存时间稍微短一点,错开那种刚好过期的时间点就好了 //比如 token 900秒(15分钟)到期,你就设置redis的key 720秒(12分钟)到期,完美错开 AssumeRoleResponse token = token(); // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build( params.getStsEndpoint(), token.getCredentials().getAccessKeyId(), token.getCredentials().getAccessKeySecret(), token.getCredentials().getSecurityToken() ); //过期时间尽量短一点 1-3 分钟即可, //只要前端能够显示出来就行了 (时间太长,可能会被人恶意访问造成流量泄露,产生大量费用。切记!!!!) //以前小白的时候直接生成10年有效的链接。。。现在看起来是真的虎 Long expirationTime = System.currentTimeMillis() + params.getStsEffectiveTime(); Date expirationDate = new Date(expirationTime); filePathList.forEach(filePath -> { //生成GET请求链接 URL url = ossClient.generatePresignedUrl(params.getStsBucketName(), filePath, expirationDate); resultMap.put(filePath, url.toString()); }); return resultMap; } } 用postman点一下看看

在这里插入图片描述 返回一堆东西!说明功夫没白费

来到前端工作

本人是个写后端的 前端没怎么学,但只需要知道大概原理即可 首先去GitHub 下载两个 sdk 文件 在这里插入图片描述

再写个HTML试试水 (建个VUE项目太麻烦 索性就写个HTML玩玩儿) DOCTYPE html> var params = { accessKeyId: "对应上一步接口返回的 {credentials.accessKeyId}", accessKeySecret: "对应上一步接口返回的 {credentials.accessKeySecret}", stsToken: "对应上一步接口返回的 {credentials.securityToken}", region: "你创建桶的区域 例如:oss-cn-chengdu", bucket: "你创建的桶名称" } function getOssClient() { return new OSS({ ...params }) } function uploadFile() { let client = getOssClient(); var file = document.getElementById('file').files; console.info(file[0].name); console.info(client); //这里是两个参数 var1 = 你的文件全路径(包括文件名), var2 文件原件 var rep = client.put("/web_files/test/" + file[0].name, file[0]) console.info(rep); }

好了!试试看,选一个文件,就把这个js文件传上去看看 在这里插入图片描述 发现返回了貌似链接的东西 我们只需要把这个链接传给后端保存起来就OK了 在这里插入图片描述 再去控制台看看到底有没有 在这里插入图片描述

在这里插入图片描述

好了赶紧去点赞收藏吧



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3