前言
阿里云oss上传文件蕴含有好多SDK,个别像客户端的百度云盘这样的C端会应用如java相干的SDK,而浏览器端,也就是web端最好应用browser.js相干的SDK,上面就来解说下如何应用,心愿可能帮忙到大家。
配置ram权限获取sts token和跨域反对
在应用阿里云OSS上传文件之前,要提前配置好ram相干权限,官网文档有阐明,具体请看应用STS长期拜访凭证拜访OSS,配置时,要留神两点:
1、因为会应用上传和下载两种权限,所以应该应用上面权限策略(xxx为你的门路):
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:PutObject", "oss:GetObject" ], "Resource": [ "acs:oss:*:*:xxx", "acs:oss:*:*:xxx/*" ] } ]}
配置好之后,咱们再来配置后盾,返回sts token
给前端
@Override public AssumeRoleResponse getAcsForUploadFile(String userName) { // STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。 String endpoint = aliyunOssConfig.getRamStsEndpoint(); // 填写步骤1生成的拜访密钥AccessKey ID和AccessKey Secret。 String AccessKeyId = aliyunOssConfig.getRamAccessKeyId(); String accessKeySecret = aliyunOssConfig.getRamAccessKeySecret(); // 填写步骤3获取的角色ARN。 String roleArn = aliyunOssConfig.getRamRoleArn(); // 自定义角色会话名称,用来辨别不同的令牌,例如可填写为SessionTest。 String roleSessionName = userName; // 以下Policy用于限度仅容许应用长期拜访凭证向指标存储空间examplebucket上传文件。 // 长期拜访凭证最初取得的权限是步骤4设置的角色权限和该Policy设置权限的交加,即仅容许将文件上传至指标存储空间examplebucket下的exampledir目录。// String policy = "{" +// " \"Version\": \"1\", " +// " \"Statement\": [" +// " {\n" +// " \"Action\": [" +// " \"oss:PutObject\"" +// " ]," +// " \"Resource\": [" +// " \"acs:oss:*:*:com-seaurl-cdn/space\"," +// " \"acs:oss:*:*:com-seaurl-cdn/space/*\"," +// " ]," +// " \"Effect\": \"Allow\"" +// " }" +// " ]" +// "}"; try { // regionId示意RAM的地区ID。以华东1(杭州)地区为例,regionID填写为cn-hangzhou。也能够保留默认值,默认值为空字符串("")。 String regionId = aliyunOssConfig.getRegion(); // 增加endpoint。实用于Java SDK 3.12.0及以上版本。 DefaultProfile.addEndpoint(regionId, "Sts", endpoint); // 增加endpoint。实用于Java SDK 3.12.0以下版本。 // DefaultProfile.addEndpoint("",regionId, "Sts", endpoint); // 结构default profile。 IClientProfile profile = DefaultProfile.getProfile(regionId, AccessKeyId, accessKeySecret); // 结构client。 DefaultAcsClient client = new DefaultAcsClient(profile); final AssumeRoleRequest request = new AssumeRoleRequest(); // 实用于Java SDK 3.12.0及以上版本。 request.setSysMethod(MethodType.POST); // 实用于Java SDK 3.12.0以下版本。 //request.setMethod(MethodType.POST); request.setRoleArn(roleArn); request.setRoleSessionName(roleSessionName); request.setPolicy(null); // 如果policy为空,则用户将取得该角色下所有权限。 request.setDurationSeconds(3600L); // 设置长期拜访凭证的无效工夫为3600秒。 final AssumeRoleResponse response = client.getAcsResponse(request); System.out.println("Expiration: " + response.getCredentials().getExpiration()); System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId()); System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret()); System.out.println("Security Token: " + response.getCredentials().getSecurityToken()); System.out.println("RequestId: " + response.getRequestId()); return response; } catch (com.aliyuncs.exceptions.ClientException e) { System.out.println("Failed:"); System.out.println("Error code: " + e.getErrCode()); System.out.println("Error message: " + e.getErrMsg()); System.out.println("RequestId: " + e.getRequestId()); return null; } }
2、设置跨域反对
如果设置了跨域规定还是不起作用,能够应用上面形式进行批改:
设置跨域规定后调用OSS时依然报“No 'Access-Control-Allow-Origin'”的谬误
上传文件(简略上传和分片上传)
下面配置好权限之后,接下来咱们来装置和应用
1、装置ali-oss
yarn add ali-oss
2、初始化oss client
留神:getAcsForUploadFile()
办法就是下面获取sts token
的申请办法
//初始化oss client客户端 async function initOssClient() { let res = await dispatch(getAcsForUploadFile()) console.log('initOss=', res) if (res.payload.status === 0) { const resData = res.payload.data const client = new OSS({ secure: true, // yourRegion填写Bucket所在地区。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。 region: 'oss-cn-hangzhou', // 从STS服务获取的长期拜访密钥(AccessKey ID和AccessKey Secret)。 accessKeyId: resData.credentials.accessKeyId, accessKeySecret: resData.credentials.accessKeySecret, // 从STS服务获取的平安令牌(SecurityToken)。 stsToken: resData.credentials.securityToken, refreshSTSToken: async () => { // 向您搭建的STS服务获取长期拜访凭证。 const refreshRes = await dispatch(getAcsForUploadFile()) console.log('refreshSTSToken info=', refreshRes) if (refreshRes.payload.status === 0) { const refreshResData = refreshRes.payload.data return { accessKeyId: refreshResData.credentials.accessKeyId, accessKeySecret: refreshResData.credentials.accessKeySecret, stsToken: refreshResData.credentials.securityToken } } }, // 刷新长期拜访凭证的工夫距离,单位为毫秒。 refreshSTSTokenInterval: 3000000, // 填写Bucket名称。 bucket: 'xxx' }); if (client) { setOssClient(client) } } }
3、上传文件
// 上传文件前判断单个文件是否超过500mb,如果超过不容许上传 function beforeUploadFile(file, fileList) { console.log('file=', file) const isLt500M = file.size / 1024 / 1024 > 500; if (isLt500M) { message.warning('超过最大文件上传大小500Mb'); return false } return true; // 不调用默认的上传办法 } // 上传文件状态回调 function onUploadFileChange(info) { console.log('info=', info) // 把没有status的文件过滤掉(没有status的文件阐明是勾销上传的文件) if (info.file.status) { setFileTaskDlg({ show: true, task: info }) if (info.file.status === 'done') { dispatch(getFileListByCid({ cid: query.cid })) } if (info.file.status === 'error') { dispatch(getFileListByCid({ cid: query.cid })) } } }// 自定义上传 function uploadFileToOss(options) { console.log('options=', options) const {file, onProgress, onSuccess, onError} = options return new Promise(async (resolve, reject) => { const filePath = `space/file/${me.name}/${file.name}` const fileType = getFileType(file.name) let result = null; // 判断文件是否超过100mb,如果超过则应用分片上传,否则应用简略上传 if (file.size / 1024 / 1024 > 100) { console.log('分片上传') // 分片上传,默认分片1Mb,如果想更改,请参考:https://help.aliyun.com/document_detail/383952.html result = await ossClient.multipartUpload(filePath, file, { progress: async (percent) => { onProgress({percent: percent * 100}) }, }).catch((error) => { onError(error) reject(error) }) } else { console.log('简略上传') // 简略上传 result = await ossClient.put(filePath, file, { progress: async (percent) => { onProgress({percent: percent * 100}) }, }).catch((error) => { onError(error) reject(error) }) } await uploadFileCallback(result, { file, filePath, fileType }, (res) => { onSuccess(res) resolve(result) }) }) } async function uploadFileCallback(result, data, callback) { const ossPath = result.res.requestUrls[0].split('?')[0] const url = ossPath.replace(/^http:\/\//i, 'https://') const newFileRes = { status: result?.res?.status, name: result?.name, url: url, } // 上传胜利之后往后台数据库插入一条文件数据 await dispatch(addFile({ fileName: data.file.name, filePath: data.filePath, fileSize: data.file.size, fileContentType: data.fileType, categoryId: query.cid, })) callback(newFileRes) }...<Upload beforeUpload={beforeUploadFile} customRequest={uploadFileToOss} showUploadList={false} withCredentials={true} disabled={btnUploadDisabled} onChange={onUploadFileChange}> <Button icon={<CloudUploadOutlined/>} disabled={btnUploadDisabled}>上传文件</Button></Upload>
beforeUploadFile()
办法是在上传文件之前做本人的业务逻辑解决,比方我这里的超过500mb的文件不容许上传
uploadFileToOss()
是Upload
组件自定义上传规定,所以你不必设置action
等属性
onUploadFileChange()
办法是上传文件时的变动回调,能够通过这个办法设置显示文件上传动静
下载文件(批量下载)
下载文件跟上传差不多,上面示例
function onDownload(d) { if (selectedRowKeys.length <= 0) { message.warning('请先抉择文件'); } else { console.log('selectedRowKeys=', selectedRowKeys) const filterFiles = files.filter(item => selectedRowKeys.includes(item.id)) console.log('filterFiles=', filterFiles) filterFiles.forEach(item => { const fileName = item.name const response = { 'content-disposition': `attachment; filename=${encodeURIComponent(fileName)}` } // 填写Object残缺门路。Object残缺门路中不能蕴含Bucket名称。 const url = ossClient.signatureUrl(item.path, {response}); const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.style.height = 0; iframe.src = url; // 与前两种形式不同,iframe须要挂载到页面上能力触发申请 document.body.appendChild(iframe); setTimeout(() => { iframe.remove(); }, 1000); }) } }
阐明:selectedRowKeys
是我的文件列表抉择的文件ids汇合item.path
是文件在oss的残缺门路,留神:不蕴含host和bucket-name,如:a/b/c.txt
总结
1、阿里云oss上传文件一开始我应用的是java sdk上传,发现不能在web端分片,于是应用了ali-oss
组件包在浏览器端上传
2、要配置ram权限以及获取sts token还有跨域
援用
js实现单个文件下载,批量下载多个文件
async/await 捕捉谬误 捕捉catch
OSS + Ant Design Upload 网页直传
OSS文档:预览或下载文件
OSS文档