使用前后端分离的模式上传文件到oss,前端直接上传文件到oss服务端,可以减少对己的服务器带宽压力,而且速度也很快,前端上传必须使用到sts临时的token授权,防止appkey和appsecret泄露。
前端使用的vue,后端使用php
1、js跨域设置
image.png image.png2、RAM账号设置
image.png1.添加用户并添加权限
image.png
2.添加角色并添加权限
image.png
3、后端使用laravel
参考链接阿里文档php生成ststoken
使用命令安装sdkcomposer require alibabacloud/sdk
<?php
namespace App\Service;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use App\Common\Enum;
use App\Exceptions\ApiException;
use Illuminate\Support\Facades\Redis;
class AliOssService{
const accessKeyId = 'my-key';
const accessKeySecret = 'my-secret';
const regionId = 'cn-shenzhen';
const stsKey = 'alists';
const bucket = 'my-bucket';
const stsExpire = 7200;
public function getSts(){
//缓存可以用就使用缓存
if($val = Redis::get(self::stsKey)){
return json_decode($val,true);
}
AlibabaCloud::accessKeyClient(self::accessKeyId,self::accessKeySecret)
->regionId(self::regionId)
->asDefaultClient();
try {
$result = AlibabaCloud::rpc()
->product('sts')
->version('2015-04-01')
->scheme('https')
->action('AssumeRole')
->method('POST')
->host('sts.aliyuncs.com')
->options([
'query'=>[
'RegionId'=>self::regionId,
//角色中的ARN值
'RoleArn'=>'acs:ram::11111111111:role/ramoss',
'RoleSessionName'=>'upload',
'DurationSeconds' => self::stsExpire,
]
])
->request();
$res = $result->toArray();
$res['Credentials']['regionId'] = self::regionId;
$res['Credentials']['bucket'] = self::bucket;
$res['Credentials']['endpoint'] = "https://oss-".self::regionId.".aliyuncs.com";
//缓存2个小时,提前1分钟过期
Redis::setex(self::stsKey,self::stsExpire-60,json_encode($res));
return $res;
}catch (ClientException $e){
throw new ApiException($e->getErrorMessage(),Enum::erCodeSystem);
}catch (ServerException $e){
throw new ApiException($e->getErrorMessage(),Enum::erCodeSystem);
}
}
}
4、前端vue代码
使用命令npm i ali-oss
安装
html 部分
<template>
<el-upload
class="avatar-uploader"
action=""
:show-file-list="false"
:http-request="fnUploadRequest"">
<img v-if="temp.image" :src="temp.image" style="width:320px;height: 202px;">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<template>
js部分 参考阿里js上传部分
可以单独抽出oss上传功能封装成模块使用,这里就不在叙述,以免太复杂了小朋友看不懂
<script>
import OSS from 'ali-oss'
export default {
name: 'oss',
data() {
return {
sts:{}
}
methods: {
let _this = this
//请求php后台获取ststoken
await ossGetToken({}).then(res=>{
_this.sts = res.data.Credentials
}).catch(res=>{
console.log(res)
})
async fnUploadRequest(options) {
const client = new OSS({
region: this.sts.regionId,
accessKeyId: this.sts.AccessKeyId,
accessKeySecret: this.sts.AccessKeySecret,
stsToken: this.sts.SecurityToken,
bucket: this.sts.bucket,
secure:true,
endpoint:this.sts.endpoint,
})
let file = options.file;
let timestamp = Date.parse(new Date())/1000
//文件名可以自定义
const fileName = `${timestamp}_${file.name}`
await client.multipartUpload(fileName,file,{
//防止覆盖
headers: { "x-oss-forbid-overwrite": true },
//上传进度
progress:(p,cpt,res)=>{
console.log(p*100+'%')
}
}).then(res=>{
//获取上传文件的oss地址
this.temp.image = res.res.requestUrls[0].split('?')[0]
}).catch(res=>{})
}
}
}
<script>
网友评论