0


前端、后端上传文件到OSS,简明记录

前端、后端上传文件到OSS,简明记录

上传文件到oss的方式:

后端上传:文件先要从页面上传到后端存起来,再通过后端发送到oss,然后后端将存起来的文件删除(当然可以不删)。

前端上传:文件通过前端页面直接上传到OSS服务器,不需要传到后端服务器,但是要先从后端获取上传OSS的凭证,然后再上传到OSS。

后端上传

后端上传的方式,官网有现成的sdk,非常简单,导入依赖后,对着代码传送你要上传的文件到后端即可

添加maven依赖

<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version></dependency>

复制下面代码到JUnit中执行了一下,更改对应的endpoint、bucketName等参数,即可执行文件上传到oss,不过对应的accessKey、accessKeySecret参数都存放在环境变量中,这也是阿里云推荐这么操作,为了安全起见以及代码与配置分离。当然你也可以直接在代码中或properties、yml文件中配置。

@TestpublicvoidtestOSSUpload()throwscom.aliyuncs.exceptions.ClientException{// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。String endpoint ="https://oss-cn-nanjing.aliyuncs.com";// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider =CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填写Bucket名称,例如examplebucket。String bucketName ="othersitefiles";// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。String objectName ="exampledir/exampleobject.jpg";// 创建OSSClient实例。OSS ossClient =newOSSClientBuilder().build(endpoint, credentialsProvider);try{File file =newFile("D:\\Bruce\\dog.jpg");ByteArrayOutputStream bos =newByteArrayOutputStream();try(InputStream is =newFileInputStream(file)){byte[] buffer =newbyte[1024];int readCount;while((readCount = is.read(buffer))!=-1){
                    bos.write(buffer,0, readCount);}}catch(FileNotFoundException e){thrownewRuntimeException(e);}catch(IOException e){thrownewRuntimeException(e);}

            ossClient.putObject(bucketName, objectName,newByteArrayInputStream(bos.toByteArray()));}catch(OSSException oe){System.out.println("Caught an OSSException, which means your request made it to OSS, "+"but was rejected with an error response for some reason.");System.out.println("Error Message:"+ oe.getErrorMessage());System.out.println("Error Code:"+ oe.getErrorCode());System.out.println("Request ID:"+ oe.getRequestId());System.out.println("Host ID:"+ oe.getHostId());}catch(ClientException ce){System.out.println("Caught an ClientException, which means the client encountered "+"a serious internal problem while trying to communicate with OSS, "+"such as not being able to access the network.");System.out.println("Error Message:"+ ce.getMessage());}finally{if(ossClient !=null){
                ossClient.shutdown();}}}

因为是在idea中执行的JUnit测试上传,所以环境变量需要再ide中配置。

image-20240401172119410

image-20240401172213302

如果是在idea中运行web项目测试,则可以在ide中配置环境变量,也可以在系统环境变量中进行配置,如果两者都设置了,则优先会从ide中获取配置。

而如果是发布以后的web项目,则就必须在系统环境变量中去设置。

image-20240401172655418

image-20240401172722147


前端上传:

既然要上传到oss,其实就不用上传后端,最好是由前端安全的把文件传到oss,这种操作最为合理。

这是后需要先到阿里云去配置账户与角色

image-20240401173106764

image-20240401173149755

image-20240401173239380

image-20240401173414993

在这里可以得到你新建账户的accessKeyaccessSecret,然后给这个用户添加权限

image-20240401173542192

image-20240402000609315

然后再新增角色

image-20240401173731574

image-20240401173745059

image-20240401173805942

image-20240401173849002

image-20240401173904834

image-20240401173926755

为角色也添加权限后,找到AEN的值,在代码中会用到

image-20240401174031115

后端代码:

service:

这里基本把参数都配置到环境变量中了

@Service("fileUploadOSSService")publicclassFileUploadOSSServiceImplimplementsFileUploadService{privateLogger logger =LoggerFactory.getLogger(FileUploadOSSServiceImpl.class);@OverridepublicRgetToken(@CurrentUserPCUsersVO usersVO){try{EnvironmentVariableCredentialsProvider credentialsProvider =CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();String region =System.getenv("REGION");String rolearn =System.getenv("ROLEARN");// 初始化默认profile,填入您的AK信息DefaultProfile profile =DefaultProfile.getProfile(
                    region, credentialsProvider.getCredentials().getAccessKeyId(), credentialsProvider.getCredentials().getSecretAccessKey());// 创建DefaultAcsClient实例并初始化IAcsClient client =newDefaultAcsClient(profile);// 创建AssumeRoleRequest请求对象AssumeRoleRequest request =newAssumeRoleRequest();

            request.setRoleArn(rolearn);
            request.setRoleSessionName("MySession");// 可选设置会话持续时间,默认为900秒
            request.setDurationSeconds(900L);// 发起请求并获取响应AssumeRoleResponse response = client.getAcsResponse(request);// 解析并打印临时凭证信息String accessKeyId = response.getCredentials().getAccessKeyId();String accessKeySecret = response.getCredentials().getAccessKeySecret();String securityToken = response.getCredentials().getSecurityToken();String endpoint =System.getenv("OSS_ENDPOINT");String bucket =System.getenv("BUCKET");System.out.println("临时AccessKeyId: "+ accessKeyId);System.out.println("临时AccessKeySecret: "+ accessKeySecret);System.out.println("临时SecurityToken: "+ securityToken);OSSVO ossVO =newOSSVO();
            ossVO.setAccessKeyId(accessKeyId);
            ossVO.setAccessKeySecret(accessKeySecret);
            ossVO.setSecurityToken(securityToken);
            ossVO.setEndpoint(endpoint);
            ossVO.setExpiration(response.getCredentials().getExpiration());
            ossVO.setBucketName(bucket);
            ossVO.setRegion(region);

            ossVO.setFileName(RandomUtils.getUUID()+System.currentTimeMillis()+ usersVO.getUid());returnR.ok().put("data", ossVO);}catch(ClientException e){
            e.printStackTrace();
            logger.error("获取token失败,com.aliyun.oss.ClientException:", e);}catch(ServerException e){
            e.printStackTrace();
            logger.error("获取token失败,ClientException:", e);}catch(com.aliyuncs.exceptions.ClientException e){
            e.printStackTrace();
            logger.error("获取token失败,com.aliyuncs.exceptions.ClientException:", e);}returnR.error("获取token失败");}}

image-20240402001642443

BUCKET为Bucket名称
image-20240402001824721

OSS_ACCESS_KEY_ID与OSS_ACCESS_KEY_SECRET则是刚才创建RAM用户的AccessKey ID与 Accesskey Secret

image-20240402002050534

OSS_ENDPOINT为Endpoint

image-20240402002306488

ROLEARN就是在角色那里的ARN值

image-20240402002923551

OSS_SESSION_TOKEN不用管,REGION为地区,一般就是Endpoint中的地区,按理我这里应该对应是cn-nanjing,但是查了下对照表,cn-nanjing的对应REGION应该是cn-hangzhou,所以我这里填的是cn-hangzhou

image-20240402002532426

目前阿里云在中国大陆地区的regionId主要有:

  • cn-hangzhou
  • cn-beijing
  • cn-shanghai
  • cn-qingdao
  • cn-zhangjiakou
  • cn-huhehaote
  • cn-shenzhen
  • cn-chengdu
  • cn-hongkong
  • cn-hangzhou-internal

**根据阿里云的官方文档,南京节点(Nanjing)并未单独作为一个regionId列出,而是作为华东2(Hangzhou)的一部分。所以,如果在南京节点使用OSS服务,应该使用

cn-hangzhou

作为regionId。**

controller:
@Api("文件上传")@RestController@RequestMapping("/pcApi/fileUpload")publicclassFileUploadController{@Autowired@Qualifier("fileUploadOSSService")privateFileUploadService fileUploadOSSService;@ApiOperation("获取OSS token")@PostMapping("/getOSSToken")publicRgetOSSToken(@CurrentUserPCUsersVO usersVO){return fileUploadOSSService.getToken(usersVO);}}

前端代码:

<!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title></head><body><divid="app"><!-- HTML部分 --><inputtype="file"id="fileInput"accept="image/*"ref="fileInput"@change="uploadFile"/></div></body><scriptsrc="js/jquery-1.10.2.min.js"></script><scriptsrc="js/vue.min.js"></script><scriptsrc="node_modules/ali-oss/dist/aliyun-oss-sdk.min.js"></script><script>var app =newVue({el:"#app",data:{},created(){},methods:{uploadFile(event){const file = event.target.files[0];// 获取文件后缀名var fileExtension = file.name.substring(file.name.lastIndexOf('.')+1);// 转换为小写以便不区分大小写比较
                    fileExtension = fileExtension.toLowerCase();debugger;// 确保文件已选择if(file){// 上传文件的逻辑const token ="eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7InVpZCI6MiwidXNlcm5hbWUiOiJ6aGFuZ2RpIiwidHlwZSI6MX19._ADwwEioEnyV7L_xqPjWZgeR_13ow5uDU01Togtr90I";// 根据实际情况从存储中获取token// 前端请求后端获取临时凭证
                        $.ajax({url:"http://localhost:8099/pcApi/fileUpload/getOSSToken",dataType:"json",method:"POST",headers:{"token": token
                            },success:function(data){if(data.code ==0){
                                    console.log(data.data);const credentials = data.data;// 初始化OSS客户端const client =newOSS({region: credentials.region,accessKeyId: credentials.accessKeyId,accessKeySecret: credentials.accessKeySecret,bucket: credentials.bucketName,stsToken: credentials.securityToken,endpoint: credentials.endpoint,// 使用STS提供的EndpointrefreshSTSToken:this.getNewSTSToken,refreshSTSTokenInterval:300000,// 设置STS Token刷新间隔,单位是毫秒,默认值是300000(即5分钟)});// 开始上传文件try{const result = client.put('weiqingview/'+credentials.fileName +'.'+ fileExtension, file);debugger;
                                        console.log('Upload successful:', result);}catch(error){
                                        console.error('Failed to upload file:', error);}}}});}},// 在初始化OSS客户端之后定义一个函数用来获取新的STS TokengetNewSTSToken(callback){
                    $.ajax({url:"http://localhost:8099/pcApi/fileUpload/getOSSToken",dataType:"json",method:"POST",headers:{"token": token // 这里的token应该来自实际的用户认证信息或者存储中的有效token},success:function(data){if(data.code ===0){const newCredentials = data.data;callback(null,{accessKeyId: newCredentials.accessKeyId,accessKeySecret: newCredentials.accessKeySecret,securityToken: newCredentials.securityToken
                                });}else{// 处理错误,例如重新获取或其他逻辑
                                console.error('Failed to fetch new STS Token:', data.message);callback(newError(data.message));}},error:function(xhr, status, err){// 请求失败处理
                            console.error('Error while fetching new STS Token:', err);callback(err);}});}}});</script></html>

对照着需要引入jquery与vue,而aliyun-oss-sdk.min.js需要通过npm 或yarn安装一下,或者引入cdn也行

npminstall ali-oss --save# 或者yarnadd ali-oss

运行

image-20240402003730282

image-20240402003846053

发现图片已经上传到oss


本文转载自: https://blog.csdn.net/dante1987/article/details/137251584
版权归原作者 黯然神伤888 所有, 如有侵权,请联系我们删除。

“前端、后端上传文件到OSS,简明记录”的评论:

还没有评论