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

07-19 1001阅读

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

上传文件到oss的方式:

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

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

后端上传

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

添加maven依赖

        
            com.aliyun.oss
            aliyun-sdk-oss
            3.15.1
        

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

@Test
    public void testOSSUpload() throws com.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 = new OSSClientBuilder().build(endpoint, credentialsProvider);
        try {
            File file = new File("D:\\Bruce\\dog.jpg");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try (InputStream is = new FileInputStream(file)) {
                byte[] buffer = new byte[1024];
                int readCount;
                while ((readCount = is.read(buffer)) != -1) {
                    bos.write(buffer, 0, readCount);
                }
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(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中配置。

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

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

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

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

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

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


前端上传:

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

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

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

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

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

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

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

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

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

然后再新增角色

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

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

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

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

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

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

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

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

后端代码:

service:

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

@Service("fileUploadOSSService")
public class FileUploadOSSServiceImpl implements FileUploadService {
    private Logger logger = LoggerFactory.getLogger(FileUploadOSSServiceImpl.class);
    @Override
    public R getToken(@CurrentUserPC UsersVO 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 = new DefaultAcsClient(profile);
            // 创建AssumeRoleRequest请求对象
            AssumeRoleRequest request = new AssumeRoleRequest();
            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 = new OSSVO();
            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());
            return R.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);
        }
        return R.error("获取token失败");
    }
}

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

BUCKET为Bucket名称

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

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

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

OSS_ENDPOINT为Endpoint

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

ROLEARN就是在角色那里的ARN值

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

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

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

目前阿里云在中国大陆地区的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")
    public class FileUploadController {
        @Autowired
        @Qualifier("fileUploadOSSService")
        private FileUploadService fileUploadOSSService;
        @ApiOperation("获取OSS token")
        @PostMapping("/getOSSToken")
        public R getOSSToken(@CurrentUserPC UsersVO usersVO) {
            return fileUploadOSSService.getToken(usersVO);
        }
    }
    

    前端代码:

    
    	
    		
    		
    	
    	
    		
    var app = new Vue({ 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 = new OSS({ region: credentials.region, accessKeyId: credentials.accessKeyId, accessKeySecret: credentials.accessKeySecret, bucket: credentials.bucketName, stsToken: credentials.securityToken, endpoint: credentials.endpoint, // 使用STS提供的Endpoint refreshSTSToken: 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 Token getNewSTSToken(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(new Error(data.message)); } }, error: function(xhr, status, err) { // 请求失败处理 console.error('Error while fetching new STS Token:', err); callback(err); } }); } } });

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

    npm install ali-oss --save
    # 或者
    yarn add ali-oss
    

    运行

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

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

    发现图片已经上传到oss

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]