美文网首页
vue thinkphp实现腾讯云对象存储COS图片上传

vue thinkphp实现腾讯云对象存储COS图片上传

作者: ArslanRobot | 来源:发表于2024-02-20 09:09 被阅读0次
    • 环境:
      thinkphp6
      vue2
      vant2.12
    • composer安装qcloud-sts-sdk
    composer require qcloud_sts/qcloud-sts-sdk
    
    • 获取COS临时id、key的sts接口
    <?php
    declare (strict_types = 1);
    
    namespace app\index\controller;
    use QCloud\COSSTS\Sts;
    
    class CosController
    {
    
        //http://localhost:8516/index/cos/sts
        public function sts() {
            $sts = new Sts();
            $config = array(
                'url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致
                'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
                'proxy' => '',
                'secretId' => 'xxxx', // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
                'secretKey' => 'xxxx', // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
                'bucket' => 'test-1253653367',//'test-1253653367', // 换成你的 bucket
                'region' => 'ap-shanghai', // 换成 bucket 所在园区
                'durationSeconds' => 1800, // 密钥有效期
                'allowPrefix' => array('2024/msc2024/*'), // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
                // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
                'allowActions' => array (
                    // 简单上传
                    'name/cos:PutObject',
                    'name/cos:PostObject',
                    // 分片上传
                    'name/cos:InitiateMultipartUpload',
                    'name/cos:ListMultipartUploads',
                    'name/cos:ListParts',
                    'name/cos:UploadPart',
                    'name/cos:CompleteMultipartUpload'
                ),
                // 临时密钥生效条件,关于condition的详细设置规则和COS支持的condition类型可以参考 https://cloud.tencent.com/document/product/436/71306
                // "condition" => array(
                //     "ip_equal" => array(
                //         "qcs:ip" => array(
                //             "10.217.182.3/24",
                //             "111.21.33.72/24",
                //         )
                //     )
                // )
            );
    
            $tempKeys = $sts->getTempKeys($config);
            //echo json_encode($tempKeys);
            return json($tempKeys);
    
            // try {
            //     // 可能抛出异常的代码
            //     // 获取临时密钥,计算签名
            //     $tempKeys = $sts->getTempKeys($config);
            //     //echo json_encode($tempKeys);
            //     return json($tempKeys);
            // } catch (\Throwable $e) {
            //     // 异常处理代码
            //     return json(array('code'=>101, 'msg'=>$e->getMessage()));
            // }
        }
    }
    
    

    前端vue2代码,使用vant的文件上传组件

    <van-uploader :after-read="handleUpload"></van-uploader>
    
    data: {
      process: 0,
      isProcessVisible: false,
      uploadType: null, //1人像 2国徽 3自拍
      cos: null
    }
    
    handleUpload: function (res) {
      var file = res.file
      var that = this
      var that = this
      var cosBucket = 'test-123456'
      var cosRegion = 'ap-shanghai'
      var cosPrefix = '2024/msc2024'
      let name = file.name
      let size = file.size
      let ext = getFilePointExtName(name)
      let shortName = getFileName(name)
      let fileName = 'upload/' + getStrDateNoLine(new Date()) + "/" + uuid() + ext
      let fileKey = cosPrefix + '/' + fileName
    
      if(ext!= '.jpg' && ext!= '.JPG' && ext!= '.png' && ext!= '.PNG') {
        //this.$Message.error('请上传jpg格式文件');
        vant.Toast('请上传jpg或png格式文件');
        return
      }
    
      if(size > 1024*1024*2) {
        vant.Toast('图片文件不要大于2M');
        return
      }
      //alert(fileName)
      //console.log(file)
      if(this.cos == null) {
        this.cos = new COS({
          // getAuthorization 必选参数
          getAuthorization: function (options, callback) {
            // 初始化时不会调用,只有调用 cos 方法(例如 cos.putObject)时才会进入
            // 异步获取临时密钥
            // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
            // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
            // STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048
            const url = '/index/cos/sts'; // url 替换成您自己的后端服务
            const xhr = new XMLHttpRequest();
            let data = null;
            let credentials = null;
            xhr.open('GET', url, true);
            xhr.onload = function (e) {
                try {
                  data = JSON.parse(e.target.responseText);
                  credentials = data.credentials;
                } catch (e) {
                }
                if (!data || !credentials) {
                  return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2))
                };
                callback({
                  TmpSecretId: credentials.tmpSecretId,
                  TmpSecretKey: credentials.tmpSecretKey,
                  SecurityToken: credentials.sessionToken,
                  // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
                  StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
                  ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
              });
            };
            xhr.send();
          }
        });
      }
    
      // var cos = new COS({
      //   SecretId: 'xx',
      //   SecretKey: 'xx',
      // });
      that.isProcessVisible = true
      that.process = 0
      this.cos.uploadFile({
        Bucket: cosBucket, /* 填写自己的bucket,必须字段 */
        Region: cosRegion,     /* 存储桶所在地域,必须字段 */
        Key: fileKey,              /* 存储在桶里的对象键(例如:1.jpg,a/b/test.txt,图片.jpg)支持中文,必须字段 */
        Body: file, // 上传文件对象
        SliceSize: 1024 * 1024 * 5,     /* 触发分块上传的阈值,超过5MB使用分块上传,小于5MB使用简单上传。可自行设置,非必须 */
        onProgress: function(progressData) {
          //console.log(JSON.stringify(progressData));
          that.process = Math.floor(progressData.percent*100)
        }
      }, function(err, data) {
        that.isProcessVisible = false
        if (err) {
          console.log('上传失败', err);
        } else {
          console.log('上传成功');
          console.log('http://' + data.Location)
            var url = 'http://' + data.Location.replace("xxxx.cos.ap-shanghai.myqcloud.com", "cdn.xxx.xxx.com")
          console.log(url)
        }
      });
      return false
    },
    
    • 用到的其它方法
    function getFileName(fileName) {
      let pos = fileName.indexOf(".")
      if(pos >= 0) {
        return fileName.substr(0, pos)
      }
      return fileName
    }
    
    function getFileExtName(fileName) {
      let pos = fileName.indexOf(".")
      if(pos >= 0) {
        return fileName.substr(pos+1)
      }
      return ''
    }
    
    function getFilePointExtName(fileName) {
      var ext = getFileExtName(fileName)
      if(ext != '') {
        return '.' + ext
      }
      return ''
    }
    
    function getStrDateNoLine(date) {
      var y = date.getFullYear();
      var m = date.getMonth() + 1;//获取当前月份的日期 
      var d = date.getDate();
      if (m < 10) {
        m = '0' + m;
      }
      if (d < 10) {
        d = '0' + d;
      }
      return y + "" + m + "" + d;
    }
    
    //用于生成uuid
    function S4() {
      return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }
    
    function uuid() {
      return (S4() + S4() + "" + S4() + "" + S4() + "" + S4() + "" + S4() + S4() + S4());
    }
    

    相关文章

      网友评论

          本文标题:vue thinkphp实现腾讯云对象存储COS图片上传

          本文链接:https://www.haomeiwen.com/subject/bglbadtx.html