前言
阿里云 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 文档