阿里云文档示例:微信小程序直传实践 - 对象存储 OSS - 阿里云
因为在客户端进行直传,此种做法并不推荐,相当于把oss的ossAccessKey,secret等信息放在了前端,并不安全,因此为了数据安全,建议使用签名方式上传文件。
这里采用了服务端签名的做法,所以我们上传oss的签名来自于后端的接口
先封装一个方法,此方法就作用于,请求后端接口,后端返回给我们一些签名数据之类的
/*
1. 获取阿里云信息,不建议前端直接获取,这样会把accessKey等等私密信息暴露到前端,
建议采用 前端请求后端,而后端对oss进行一系列的加密等操作 将信息返回给前端
*/
async function getAliOssInfo() {
let [err, res] = await uni.request({
url: 'https://www.example.com/api/oss/info'
});
return res
}
再封装一个方法
export async function uploadOss({
filePath
}) {
let resp = await getAliOssInfo() //请求后台获取oss信息
//直接获取code可能不太对。。。可能外面还有一层
if (resp.code === 200) {
let {
data
} = resp //根据后台返回的值而取
let fileType = filePath.substring(filePath.lastIndexOf('.')) || '.jpg' //获取图片类型后缀 .jpg .png
// 正常的情况下,我们上传到oss都需要对文件进行重新命名以便我们进行更加合理的管理方式,
// 比如 项目名称/模块名称/年/月/日/随意的字符串.图片格式 ,这里我就只获取图片格式了,
let key = `test123${fileType}` //那么我们上传到oss上,路径就是 test123.png || test123.jpg ...
let [err, result] = await uni.uploadFile({
url: data.host, //阿里云的存储地址,可以后端返回给你,也可以前端自己写上
filePath, //要上传的临时文件路径
name: 'file',
formData: {
key, //文件名
policy: data.policy, //后台获取超时时间
OSSAccessKeyId: data.accessid, //后台获取临时ID
success_action_status: '200', //让服务端返回200,不然,默认会返回204
signature: data.signature //后台获取签名
}
})
if (err) {
// 上传错误了。。。可以做点什么
} else {
return key //上传成功后,将我们所自定义的key(文件路径名)返回出去
}
}
}
调用,result就是我们的上传到阿里云oss后路径了,当然此路径是我们自定义的,即上方的key值。
async click() {
uni.chooseImage({
count: 1,
success: async res => {
let result = await uploadOss(res.tempFilePaths[0]);
}
});
}
在写uniapp项目的时候,我不太喜欢用原生自带的uni.request进行请求,大部分都会选择一个请求库,或者自己做点简单的封装,这边我比较推荐的是luch大神的luch-request请求库:
插件地址:luch-request - DCloud 插件市场
官网地址:luch-request
同时luch-request,也是我所维护的uview2的请求库,uview2对此进行了简单的封装,还真的挺好用的,我也附上一份luch-request的oss请求代码,多少修修改改就可以了
import http from "../http.js"; //引入luch-request封装的请求拦截,响应拦截
/*
1. 获取阿里云信息,不建议前端直接获取,这样会把accessKey等等私密信息暴露到前端,
建议采用 前端请求后端,而后端对oss进行一系列的加密等操作 将信息返回给前端
*/
function getAliOssInfo() {
return http.post('/api/oss/info') //接口由后台提供
}
/*
2. 图片上传到oss
*/
export async function uploadOss({
filePath
}) {
let resp = await getAliOssInfo() //请求后台获取oss信息
if (resp.code === 200) {
let {
data
} = resp //根据后台返回的值而取
let fileType = filePath.substring(filePath.lastIndexOf('.')) || '.jpg' //获取图片类型后缀 .jpg .png
// 正常的情况下,我们上传到oss都需要对文件进行重新命名以便我们进行更加合理的管理方式,
// 比如 项目名称/模块名称/年/月/日/随意的字符串.图片格式 ,这里我就只获取图片格式了,
let key = `test123${fileType}` //那么我们上传到oss上,路径就是 test123.png || test123.jpg ...
let result = await http.upload(data.host, {
filePath,
formData: {
key, //文件名
policy: data.policy, //后台获取超时时间
OSSAccessKeyId: data.accessid, //后台获取临时ID
success_action_status: '200', //让服务端返回200,不然,默认会返回204
signature: data.signature //后台获取签名
}
})
console.log(result)
return key //上传成功后,将我们所自定义的key(文件路径名)返回出去
}
}