*新闻详情页*/>
腾讯云COS官网地址:
之所以不选阿里云的OSS,或者华为云的OBS,是因为他们都要收费。而腾讯云COS有半年免费50G的存储服务。当然还可以选择七牛云,但七牛云需要实名认证(暂时还没有认证通过,就先拿腾讯云来练手了)。
2、创建密钥
自定义域名的教程,看官方文档:
3、thinkphp后端:计算腾讯云COS对象存储签名特别说明:由于签名计算放在前端会暴露 SecretId 和 SecretKey, 所以我们把签名计算过程放在后端实现,前端通过 ajax 向后端获取签名结果,正式部署时请在后端加一层自己网站本身的权限检验。
thinkphp控制器controller中的代码:
?php namespace app\index\controller; use think\Controller; use think\Request; /**引入类库方式一(extend/sts.php)*/ import('sts', EXTEND_PATH); class Car extends Controller{ * 获取腾讯云COS对象存储签名 * https://cloud.tencent.com/product/cos public function getSts(){ $sts = new \STS(); // 配置参数 $config = array( 'url' = 'https://sts.tencentcloudapi.com/', 'domain' = 'sts.tencentcloudapi.com', 'proxy' = '', 'secretId' = '你cos密钥中的secretId', // 固定密钥 'secretKey' = '你cos密钥中的secretKey', // 固定密钥 'bucket' = 'myfaka-1256433534',//你的存储桶名称bucket 'region' = 'ap-guangzhou', // bucket所在地域 'durationSeconds' = 1800, // 密钥有效期 'allowPrefix' = '*', // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg // 密钥的权限列表。简单上传需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923 'allowActions' = array ( // 简单上传 'name/cos:PutObject', 'name/cos:PostObject', // 获取临时密钥,计算签名 $tempKeys = $sts- getTempKeys($config); // 返回数据给前端 header('Content-Type: application/json'); header('Access-Control-Allow-Origin: http://127.0.0.1'); // 这里修改允许跨域访问的网站 header('Access-Control-Allow-Headers: origin,accept,content-type'); echo json_encode($tempKeys); ?
extend/sts.php的代码:(这是官方提供的类)
?php * 代码出处: * https://github.com/tencentyun/qcloud-cos-sts-sdk class STS{ // 临时密钥计算样例 function _hex2bin($data) { $len = strlen($data); return pack( H . $len, $data); // obj 转 query string function json2str($obj, $notEncode = false) { ksort($obj); $arr = array(); if(!is_array($obj)){ throw new Exception($obj + must be a array foreach ($obj as $key = $val) { array_push($arr, $key . '=' . ($notEncode ? $val : rawurlencode($val))); return join(' ', $arr); // 计算临时密钥用的签名 function getSignature($opt, $key, $method, $config) { $formatString = $method . $config['domain'] . '/?' . $this- json2str($opt, 1); $sign = hash_hmac('sha1', $formatString, $key); $sign = base64_encode($this- _hex2bin($sign)); return $sign; // v2接口的key首字母小写,v3改成大写,此处做了向下兼容 function backwardCompat($result) { if(!is_array($result)){ throw new Exception($result + must be a array $compat = array(); foreach ($result as $key = $value) { if(is_array($value)) { $compat[lcfirst($key)] = $this- backwardCompat($value); } elseif ($key == 'Token') { $compat['sessionToken'] = $value; } else { $compat[lcfirst($key)] = $value; return $compat; // 获取临时密钥 function getTempKeys($config) { if(array_key_exists('bucket', $config)){ $ShortBucketName = substr($config['bucket'],0, strripos($config['bucket'], '-')); $AppId = substr($config['bucket'], 1 + strripos($config['bucket'], '-')); if(array_key_exists('policy', $config)){ $policy = $config['policy']; }else{ $policy = array( 'version'= '2.0', 'statement'= array( array( 'action'= $config['allowActions'], 'effect'= 'allow', 'principal'= array('qcs'= array('*')), 'resource'= array( 'qcs::cos:' . $config['region'] . ':uid/' . $AppId . ':prefix//' . $AppId . '/' . $ShortBucketName . '/' . $config['allowPrefix'] $policyStr = str_replace('\\/', '/', json_encode($policy)); $Action = 'GetFederationToken'; $Nonce = rand(10000, 20000); $Timestamp = time(); $Method = 'POST'; $params = array( 'SecretId'= $config['secretId'], 'Timestamp'= $Timestamp, 'Nonce'= $Nonce, 'Action'= $Action, 'DurationSeconds'= $config['durationSeconds'], 'Version'= '', 'Name'= 'cos', 'Region'= 'ap-guangzhou', 'Policy'= urlencode($policyStr) $params['Signature'] = $this- getSignature($params, $config['secretKey'], $Method, $config); $url = $config['url']; $ch = curl_init($url); if(array_key_exists('proxy', $config)){ $config['proxy'] curl_setopt($ch, CURLOPT_PROXY, $config['proxy']); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $this- json2str($params)); $result = curl_exec($ch); if(curl_errno($ch)) $result = curl_error($ch); curl_close($ch); $result = json_decode($result, 1); if (isset($result['Response'])) { $result = $result['Response']; $result['startTime'] = $result['ExpiredTime'] - $config['durationSeconds']; $result = $this- backwardCompat($result); return $result; // get policy function getPolicy($scopes){ if (!is_array($scopes)){ return null; $statements = array(); for($i=0, $counts=count($scopes); $i $counts; $i++){ $actions=array(); $resources = array(); array_push($actions, $scopes[$i]- get_action()); array_push($resources, $scopes[$i]- get_resource()); $principal = array( 'qcs' = array('*') $statement = array( 'actions' = $actions, 'effect' = 'allow', 'principal' = $principal, 'resource' = $resources array_push($statements, $statement); $policy = array( 'version' = '2.0', 'statement' = $statements return $policy; class Scope{ var $action; var $bucket; var $region; var $resourcePrefix; function __construct($action, $bucket, $region, $resourcePrefix){ $this- action = $action; $this- bucket = $bucket; $this- region = $region; $this- resourcePrefix = $resourcePrefix; function get_action(){ return $this- action; function get_resource(){ $index = strripos($this- bucket, '-'); $bucketName = substr($this- bucket, 0, $index); $appid = substr($this- bucket, $index + 1); if(!(strpos($this- resourcePrefix, '/') === 0)){ $this- resourcePrefix = '/' . $this- resourcePrefix; return 'qcs::cos:' . $this- region . ':uid/' . $appid . ':prefix//' . $appid . '/' . $bucketName . $this- resourcePrefix;4、下载
下载地址:
5、微信小程序创建config.js,用于保存对象存储参数,代码如下:module.exports = { stsUrl: 'https://后端网址/car/getSts.html',//后端获取签名 Bucket: 'myfaka-1256433534',//存储桶名称 Region: 'ap-guangzhou',//所属地域
把cos-wx-sdk-v5.js和config.js都放到项目里:
6、index.wxml代码:!--图片上传-- view >特别说明:这里使用的是的文件上传组件,框架地址:
7、index.js代码://获取应用实例 const app = getApp() var COS = require('./cos-wx-sdk-v5.js') var config = require('./config'); //初始化COS对象 var cos = new COS({ // 获取签名 getAuthorization: function (options, callback) { wx.request({ url: config.stsUrl, // 服务端获取签名 dataType: 'json', success: function (result) { var data = result.data; var credentials = data.credentials; callback({ TmpSecretId: credentials.tmpSecretId, TmpSecretKey: credentials.tmpSecretKey, XCosSecurityToken: credentials.sessionToken, ExpiredTime: data.expiredTime, Page({ * 页面的初始数据 data: { fileList: [], date:'' * 生命周期函数--监听页面加载 onLoad: function (options) { //获取时间,作为图片文件夹名,如20191207 this.setData({ date: app.globalData.util.dateFormat(new Date(), YMD ) afterRead(event) { var that=this; // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式 const { file } = event.detail; var filePath = file.path; //var filename = filePath.substr(filePath.lastIndexOf('/') + 1); var filename = new Date().getTime() + '.'+ filePath.substr(filePath.lastIndexOf('.') + 1); //console.log( 图片文件名: + filename); //文件相对路径名 var relativePath = 'upload/' + that.data.date + '/' + filename; cos.postObject({ Bucket: config.Bucket, Region: config.Region, Key: relativePath, FilePath: filePath, onProgress: function (info) { //添加到预览中 var img={ url: app.globalData.cosUrl + relativePath, name: filename // 上传完成需要更新fileList that.setData({ fileList: that.data.fileList.concat(img) }, function (err, data) { delFile(event) { var that = this; wx.showModal({ title: '提示', content: '确定要删除这张图片吗?', success(res) { if (res.confirm) { var index = event.detail.index; var list = that.data.fileList; var filename = list[index].name; for (let i = 0; i list.length; i++) { //如果item是选中的话,就删除它。 if (index == i) { // 删除对应的索引 list.splice(i, 1); break; //删除cos对象存储中的图片 cos.deleteObject({ Bucket: config.Bucket, Region: config.Region, Key: 'upload/' + that.data.date + '/' + filename, }, function (err, data) { console.log(err); //更新数据 that.setData({ fileList: list }); wx.showToast({ title: '删除成功', icon: 'success' } else if (res.cancel) { //console.log('用户点击取消') })上面页面时间是用了工具类的,附加util.js时间格式化的代码:
const formatTime = date = { const year = date.getFullYear() const month = date.getMonth() + 1 const day = date.getDate() const hour = date.getHours() const minute = date.getMinutes() const second = date.getSeconds() return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') const formatNumber = n = { n = n.toString() return n[1] ? n : '0' + n * 时间戳转化为年 月 日 时 分 秒 * number: 传入时间戳 * format:返回格式,支持自定义,但参数必须与formateArr里保持一致 function dateFormat(number, format) { var formateArr = ['Y', 'M', 'D', 'h', 'm', 's']; var returnArr = []; var date = new Date(number); returnArr.push(date.getFullYear()); returnArr.push(formatNumber(date.getMonth() + 1)); returnArr.push(formatNumber(date.getDate())); returnArr.push(formatNumber(date.getHours())); returnArr.push(formatNumber(date.getMinutes())); returnArr.push(formatNumber(date.getSeconds())); for (var i in returnArr) { format = format.replace(formateArr[i], returnArr[i]); return format;
Copyright © 2002-2020 微信公众号平台小程序_微信打分小程序_小程序发布_小程序大全_微信小程序编程 版权所有 (网站地图) 粤ICP备10235580号