thinkphp获取阿里云oss签名
public function gmt_iso8601($time) {
$expiration = date(DATE_ISO8601,$time);
$pos = strpos($expiration, '+');
$expiration = substr($expiration, 0, $pos);
return $expiration."Z";
}
public function signedUrl(){
$id= ''; // 请填写您的AccessKeyId。
$key= ''; // 请填写您的AccessKeySecret。
// $host的格式为 bucketname.endpoint,请替换为您的真实信息。(在阿里云中可配置)
$host = '';
// $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。下面有callBack方法
$callbackUrl = '';
$dir = 'image/'; // 用户上传文件时指定的前缀。
$callback_param = array('callbackUrl'=>$callbackUrl,
'callbackBody'=>'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}',
'callbackBodyType'=>"application/x-www-form-urlencoded");
$callback_string = json_encode($callback_param);
$base64_callback_body = base64_encode($callback_string);
$now = time();
$expire = 3000; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。
$end = $now + $expire;
$expiration = $this->gmt_iso8601($end);
//最大文件大小.用户可以自己设置
$condition = array(0=>'content-length-range', 1=>0, 2=>1048576000);
$conditions[] = $condition;
// 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
$start = array(0=>'starts-with', 1=>'$key', 2=>$dir);
$conditions[] = $start;
$arr = array('expiration'=>$expiration,'conditions'=>$conditions);
$policy = json_encode($arr);
$base64_policy = base64_encode($policy);
$string_to_sign = $base64_policy;
$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));
$response = array();
$response['accessid'] = $id;
$response['host'] = $host;
$response['policy'] = $base64_policy;
$response['signature'] = $signature;
$response['expire'] = $end;
$response['callback'] = $base64_callback_body;
$response['dir'] = $dir; // 这个参数是设置用户上传文件时指定的前缀。
return $response;
}
//回调函数
public function callBack(){
header("Content-Type: application/json");
$data = array("Status"=>"Ok",'data'=>$_POST);
echo json_encode($data);
}
前端Vue OSS上传文件
创建oss.js文件
//导入request
import {
getSignature
} from './request'
let accessid = ''
let policyBase64 = ''
let signature = ''
let callbackbody = ''
let key = ''
let expire = 0
let host = ''
let g_object_name = ''
let data = []
let now = Date.parse(new Date()) / 1000
// 生成随机字符串
function random_string (len) {
len = len || 32
var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
var maxPos = chars.length
var pwd = ''
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos))
}
return pwd
}
// 获取用户上传原始文件名
function get_file_name (filename) {
let pos = filename.lastIndexOf('.')
let suffix = ''
if (pos != -1) {
suffix = filename.substring(pos)
}
return suffix
}
// 把随机生成的字符串拼接在原始上传文件名后面生成新的唯一文件名
function set_file_name (filename) {
let suffix = get_file_name(filename)
g_object_name = key + random_string(10) + suffix
return ''
}
// 获取后端返回的签名信息,生成oss参数
function oss (filename = null) {
// 可以判断当前expire是否超过了当前时间, 如果超过了当前时间, 就重新取一下, 3 s 作为缓冲。
// 调用后端服务器接口获取签名信息,利用axios返回promise,可以链式调用
return getSignature().then(res => {
res = res.data.data
// console.log(res)
/* 返回的签名策略信息包含:
{
accessid: "LTAI*******UPPr", // 用户请求的accessid
callback: "eyJjYWxs************H0ifQ==", // 回调
dir: "test/file-dir/", // 上传文件的存储位置
expire: "1557974779", // 上传策略Policy失效时间
host: "http://xxxxxxxxx.com", // 上传文件服务器地址
policy: "eyJleHBp***********6/EMG7U=" ,// 用户表单上传的策略(Policy)
signature: "JumJy*****k6/EMG7U=" // 签名信息
}
*/
policyBase64 = res['policy']
accessid = res['accessid']
signature = res['signature']
expire = parseInt(res['expire'])
callbackbody = res['callback']
host = res['host']
key = res['dir']
if (filename != null) {
set_file_name(filename)
}
// 返回表单上传需要的参数信息
return {
'host': host,
'key': g_object_name,
'policy': policyBase64,
'OSSAccessKeyId': accessid,
'success_action_status': '200', // 让服务端返回200,不然,默认会返回204
'callback': callbackbody,
'signature': signature
}
})
}
export {
oss
}
创建request.js文件
import axios from '@/libs/api.request'
// 请求方法
export const getSignature = () => {
return axios.request({
url: 'upload/get',
method: 'post'
})
}
使用oss.js(这里我用的是iview组件库)
我以iview的上传图片为例
<div class="demo-upload-list" v-for="(item, index) in imageFileList " :key="index">
<img :src="item.url">
<div class="demo-upload-list-cover">
<Icon type="ios-trash-outline" @click.native="handleRemoveImage(item)"></Icon>
</div>
</div>
<Upload
ref="upload"
:show-upload-list="false"
:format="['jpg','jpeg','png']"
:max-size="5120"
:data="uploadData"
type="drag"
:action="uploadHost"
:before-upload="beforeUpload"
:on-success="handleSuccessImage"
style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
</div>
</Upload>
引入写好的oss.js文件
// 根据自己创建的oss.js路径
import {oss} from "./oss.js"
在methods方法中写入以下代码
beforeUpload(file) {
return oss(file.name).then(res => {
this.uploadHost = res.host
this.uploadData = res
})
},
// 上传成功
handleSuccessImage(res, file, fileList) {
if (this.imageFileList.length == 0) {
this.imageFileList.push({
name: res.data.filename,
url: ossUrl + res.data.filename
})
} else {
this.imageFileList[0].name = res.data.filename
this.imageFileList[0].url = ossUrl + res.data.filename
}
},
handleRemoveImage (file) {
this.imageFileList.splice(this.imageFileList.indexOf(file), 1);
},