前言

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