阿里OSS存储的使用 PC端与小程序分别详解
程序员文章站
2024-02-02 11:30:28
...
使用场景
在PC端后台管理系统或者小程序中,都需要实现一个功能,就是:选择图片后进行上传。
我原本的理解就是 选择图片(本地或者拍摄图片)后,将图片的路径传递到后台,然后由他们进行处理即可。
但是有个问题,我说的这个图片路径是本地图片路径,如果是传递给后台,后台是拿不到这个图片的。
所以,解决的关键就是,需要有个中间的处理器,可以让本地图片上传上去,然后处理成外部链接的形式,再将这个外部链接传递给后台就可以了。 这个中间的处理器就是阿里OSS存储。
PC端使用方式
页面效果:
代码如下:
页面部分
<el-form-item label="banner图:" :label-width="formLabelWidth" prop="imageUrl">
// 上传图片的按钮,
<div>
<el-button :loading="loading" type="primary" @click="addImg()">
上传图片
<i class="el-icon-upload el-icon--right" />
</el-button>
</div>
<div
style="width:200px;height:auto;margin-top:20px;position: relative;"
@mouseenter="isShow = true"
@mouseleave="isShow = false"
>
// 如果有图片,则hover上去的时候可以进行删除或者预览图片
<span class="shade" v-show="isShow">
<i class="el-icon-delete" @click.stop="del()" />
<i class="el-icon-zoom-in" @click.stop="bosst(bannerUrl)" />
</span>
// 预览图片的时候,也是通过一个dialog弹窗实现的
<el-dialog :visible.sync="preImgVisible" class="preImg">
<img width="100%" :src="bannerUrl" alt />
</el-dialog>
// 上传图片完成后,需要展示出来
<el-image :src="bannerUrl" fit="contain" v-if="bannerUrl" />
</div>
</el-form-item>
script部分
// 引入OSS的api文件
import { client, getOssToken } from "@/api/gate";
// 预览图片,参数为图片的地址
bosst(url) {
this.bannerUrl = url;
this.preImgVisible = true;
},
// 删除图片
del(index) {
this.bannerUrl = "";
this.form.imageUrl = this.bannerUrl;
},
//选择图片
![changeImg中的file格式如下:](https://img-blog.csdnimg.cn/20200723170426254.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3llaGFvY2hlbmc1MjA=,size_16,color_FFFFFF,t_70)
changeImg(file) {
this.imgInput = false;
for (let i = 0; i < file.target.files.length; i++) {
this.pushFile(file.target.files[i], i, file);
}
},
async pushFile(files, index, file) {
const self = this;
if (files.type === "image/jpeg" || files.type === "video/mp4" || files.type === "image/gif" || files.type === "image/png") { console.log("格式正确"); } else {
this.$message.error("文件格式错误!");
return;
}
const isLt2M = files.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("上传图片大小不能超过 2MB!");
return;
}
if (index !== -1) {
this.loading = true;
}
const { result } = await getOssToken();
let point = files.name.lastIndexOf(".");
let suffix = files.name.substr(point);
let fileName = files.name.substr(0, point);
let date = Date.parse(new Date());
let fileNames = `goods/${fileName}_${date}${suffix}`;
// 此处的client就是阿里OSS的API,具体参数我还没有搞懂。
client(result).put(fileNames, files).then(result => {
// 下面是如果对返回结果再进行处理,根据项目需要
if (result.res && result.res.status === 200) {
self.loading = false;
console.log("上传图片后返回的数据", result.url);
self.bannerUrl = result.url;
self.form.imageUrl = result.url;
} else {
self.$message.error(fileName + "上传失败");
}
}).catch(err => {
self.loading = false;
self.$message.error("上传失败");
});
},
addImg() {
this.imgInput = true;
this.$nextTick(() => {
this.$refs.imgUpload.click();
});
}
小程序端使用方式
界面效果如下:
需要实现的功能有:
- 能够上传图片(拍摄或者选择本地图片)
- 加水印
页面结构如下:
<view class="img">
<view @click="chooseImage('up')" :class="disableFlag?'disabledFlag':''">
<image :src="idupImg?idupImg:'/static/IDupImg.png'" mode="aspectFit" lazy-load></image>
<text>上传身份证正面</text>
</view>
<view @click="chooseImage('down')">
<image :src="iddownImg?iddownImg:'/static/IDdownImg.png'" mode="aspectFit" lazy-load></image>
<text>上传身份证反面</text>
</view>
</view>
注意事项:
image 的 src属性,不能只绑定一个动态值
例如:<image :src="idCardUpImg"></image>
data(){
return{
idCardUpImg:"@/static/idCardUpImg"
}
}
如果是上面的这种写法,页面会不渲染。
解决方法是:
本地图片直接写入到页面中,后续改变的图片路径写入到动态值中,然后三目运算符判断的形式展示出来<image :src="idupImg?idupImg:'/static/IDupImg.png'" mode="aspectFit" lazy-load></image>
上面的这种写法就可以展示图片本地静态图片了。
script部分代码
var shuiyin = "?x-oss-process=image/resize,w_300,h_200/watermark,type_d3F5LXplbmhlaQ,size_24,text_NTjCsOWVhuWfjg,color_000000,shadow_30,rotate_315,fill_1,t_30,g_center,x_10,y_10";
//选择图片
async chooseImage(type){
// 此处的disableFlag是图片是否可以上传的开关,有些情况是禁止图片上传的。
if(this.disableFlag){
return;
}
let _this = this;
// uni自带的上传图片到额方法
uni.chooseImage({
count: 4, //最多可以选择的图片张数,默认9
sizeType: ['original', 'compressed'], //original 原图,compressed 压缩图,默认二者都有
sourceType: ['album','camera'], //album 从相册选图,camera 使用相机,默认二者都有
success: (respone)=> {
// 图片选择后,需要调用OSS的接口进行本地图片与外部图片链接的转化
_this.$request.urlRequest(
'/gate/oss/token',
{},
'GET',
function (res) {
if (res.code == 200) {
let data = res.result;
let env = {
uploadImageUrl: 'https://58d.oss-cn-hangzhou.aliyuncs.com/', // 默认存在根目录,可根据需求改
AccessKeySecret: data.AccessKeySecret, // AccessKeySecret 去你的阿里云上控制台上找
OSSAccessKeyId: data.AccessKeyId, // AccessKeyId 去你的阿里云上控制台上找
stsToken: data.SecurityToken,
timeout: 87600 //这个是上传文件时Policy的失效时间
}
uploadImage(env, respone.tempFilePaths[0], 'images/',
result => {
if(type === "up"){
_this.idupImg = result+shuiyin;
} else if(type === "down"){
_this.iddownImg = result+shuiyin;
}
}
)
}
}
)
}
});
},
// 上传图片
uploadImage: function(file){
return new Promise((resolve, reject)=> {
let formData={};
let _this = this;
//发送给后端的附加参数
// const formData = {
// thumb_mode: 1,
// };
});
},
//删除图片
delImage(index){
uni.showModal({
content: '确定要放弃这张图片么?',
success: (confirmRes)=> {
if (confirmRes.confirm) {
// this.imageList.splice(index, 1);
}
}
});
},
//预览图片
previewImage(index){
const urls = [];
// this.imageList.forEach((item)=> {
// urls.push(item.filePath);
// })
uni.previewImage({
current: urls[index],
urls: urls,
indicator: "number"
})
}