thinkphp 获取oss签名,前端vue直接oss上传文件

2 篇文章 0 订阅
1 篇文章 0 订阅

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);
},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值