目录
一.描述
二.OSS相关
一.描述
目前公司在做项目,应用的业务场景有上传,下载,预览;要求上传的文件的类型也比较多,有word,pdf,image,video,ai,psd等等这些类型,应用的是阿里云的OSS,本文就简单介绍一下前端(JS)相关的代码,用的框架是react,脚手架是antd pro4,重点介绍下阿里云相关的上传,下载,预览吧;
二.OSS相关
如果是项目的包管理工具用的是npm,应该先安装ali-oss这个包,然后通过import导入进来。
import OSS from 'ali-oss'
//如此就初始化了一个OSS的客户端,通过这个客户端可以实现上传,下载,预览等等相关的需求
const client = new OSS({
region,//这些都是你们公司在购买阿里云的时候设定的
accessKeyId: creds.AccessKeyId,//这些都是你们公司在购买阿里云的时候设定的
accessKeySecret: creds.AccessKeySecret,//这些都是你们公司在购买阿里云的时候设定的
bucket,
secure:true,//在 OSSClient 初始化时加上 secure:true 就是 https 传输了
});
- 普通上传
OSS的上传可以分为普通上传和分片上传,如果文件的体积比较小,用普通上传就可以解决了,阿里云官方建议,如果文件的体积超过100M可以采用分片上传,先来分享一下普通上传,以上传图片为例子(用的client就是上文的代码实例出来的client,此后所有的client都是这个,不再赘述)。在使用antd或者element-ui提供的Upload插件的时候,会有一个方法来覆盖插件的默认上传行为,就是覆盖默认上传行为的方法里面去调用OSS的客户端进行上传就行了;
/*
vue的UI框架element-ui的上传插件,那个:http-request里面的方法就是用来覆盖默认上传行为的,以
uploadHttp为例子来展示OSS相关的上传
*/
<el-upload
action=""
accept=".jpg,.jpeg,.png,.JPG,.JPEG,.bmp"
list-type="picture-card"
:http-request="uploadHttp"
:show-file-list="false"
:before-upload="beforeAvatarUpload">
<div class="adv-pic-box" v-if="siteForm.siteIconUrl">
<img :src="siteForm.siteIconUrl" width="150" height="150">
</div>
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
<div slot="tip" class="el-upload__tip">图片格式:jpg,jpeg,png,bmp;文件大小:不大于1M</div>
</el-upload>
OSS相关的上传代码放在了uploadHttp里面,详情如下:
uploadHttp ({ file }) {
const fileName = `/${+new Date()}/${file.name}` // 定义唯一的文件名,规则可以根据需要去自定义的
client.put(fileName, file, {
'ContentType': 'image/jpeg'
}).then(({ res, url, name }) => {
if (res && res.status === 200) {
//url 就表示文件上传成功以后服务器返回的一个可访问的链接
this.siteForm.siteIconUrl = url
}
}).catch((err) => {
this.$message.error('图片上传失败!')
console.log(`阿里云OSS上传图片失败回调`, err)
})
},
- 分片上传
分片上传是以antd的上传插件Upload为例子来展示代码的,因为分片上传要实时显示上传进度,产品方就要求加入一个进度条来显示上传 进度,监测进度这个OSS有专门的回调来处理,实在是太强大了!具体看代码吧!
/*
此处是react的UI插件antd的上传组件,这里的customRequest就是用来自定义上传行为的,在这个方法里面涉及到了OSS上传
*/
<Upload
{...uploadProps}
accept={accept}
className='ht-upload'
fileList={fileList}
listType={listType}
beforeUpload={this.handleBeforeUpload}
customRequest={this.handleCustomUpload}
onChange={this.handChange}
onRemove={this.onRemove}
>
<Button type='primary' icon={<UploadOutlined />}>{btnText}</Button>
</Upload>
//此处的progress就是实时显示上传进度的
<div className='wrap-upload' style={{ width: '100%' }}>
{
percent !== 0 && <Progress {...progressProps} percent={percent} />
}
//提示文本
<p className="ht-upload-hint">{hintText}</p>
</div>
OSS分片上传的代码:
handleCustomUpload = (params: any) => {
message.loading('正在上传......')
const { onUploadSuccess = noop } = this.props
const { file } = params
// eslint-disable-next-line @typescript-eslint/naming-convention
const this_Com: any = this
const fileName = `/${+new Date()}/${file.name}` // 定义唯一的文件名
// 此方法用来实现OSS的分片上传
client.multipartUpload(fileName, file, {
// 这个回调方法就是用来监测上传进度的,因为本人在写代码时用的是类组件,而这个方法中的this指向的不是此组件,因此就在外面声明了一个变量来缓存一下this,来达到更新上传进度的目的
progress(pct: any, checkpoint: any) {
const percent = Number(pct * 100).toFixed(0)
this_Com.setState({ percent })
}
}).then((result: any) => {
const { res } = result
if (res && res.status === 200) {
const url = res.requestUrls[0].split('?')[0]
const imgItem = {
uid: file.uid,
name: file.name,
status: 'done',
url,
imgUrl: url,
}
onUploadSuccess([ imgItem ])
this.setState({ fileList: [ imgItem ] })
message.destroy()
message.success('上传成功!')
}
}).catch((err: any) => {
message.destroy()
message.error('上传失败!')
console.log(`阿里云OSS上传图片失败回调`, err)
})
}
- 下载
点击页面上的一个按钮,或者其他用户行为触发下载,在下载时,执行下列方法:
//点击下载,调用下列方法
DownLoad = () => {
const { downName = '', uploadUrl = '' } = this.state
// 注意这个filename就是下载文件以后要显示的文件名,千万不要写错了,要不然下载下来的文件名会是乱码
const response = {
'content-disposition': `attachment; filename=${decodeURIComponent(downName)}`
}
const str = uploadUrl.indexOf('https') > -1 ? 'https' : 'http'
// 注意一下这个filePath,是上传的时候返回来的链接的全路径,要包含文件名和文件后缀
const url = client.signatureUrl(filePath, { response })
// 此时这个url就是一个可以下载的链接,可以直接在浏览器打开下载,也可以通过前端的a标签实现下载
downloadUseA(url, downName)
// 直接在浏览器打开下载的话,可以执行下列代码:
// window.open(url)
}
// 采用a标签的方式实现下载
export function downloadUseA(url: string, name: string) {
const a = document.createElement('a')
a.download = decodeURIComponent(name)
a.href = url
a.style.display = 'none'
document.body.appendChild(a)
a.click()
a.remove()
}
- 预览
我试了一下pdf 的预览,没有问题,可以正常预览,但是word不能正常预览,仔细看一下阿里云官方的这篇文章:OSS在线预览word,下方有评论说目前暂不支持word预览。
实现预览的前端代码:
// object-key表示从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
const url = client.signatureUrl('object-key', { expires: 3600 });
// 此处以设置URL的有效时长为3600s为例,若不设置有效时长,则默认为1800s。
console.log(url);
/*
这个url就是一个可预览的在线链接,可以直接在浏览器打开这个链接来预览,也可以放在iframe标签中嵌入到网页里面,具体如何预览,看你们的个人需求就行了!
把ifram头部的工具栏给隐藏掉的话,就只需在src的后面加上‘#toolbar=0’,看如下例子:
<iframe id='ifm' src={`${fileUrl}#toolbar=0`} frameBorder="0" width='100%' height={height}/>
隐藏掉工具栏以后就不能打印和下载了
*/
至此就分享完毕