vue使用腾讯云COS上传文件-很清楚的哈。

最近一个项目需要用到前端COS上传文件,网上找了很多教程都是不清不楚的,搞懂了写个文章记录。

内容有点长,一点一点看

VUE使用的是js的上传SDK,先给vue安装一下。

npm i cos-js-sdk-v5 --save

前端第一步的活儿干完了,然后就是后端,因为考虑安全问题,所以我使用了临时密钥上传

我的后端是Thinkphp6,所以采用了php的临时密钥生成的代码。

  • composer 安装临时生成密钥
如果根目录有composer.json文件则将创建"qcloud_sts/qcloud-sts-sdk": "3.0.*"加入require里面
否则创建composer.json的文件,内容如下:
{
    "require":{
        "qcloud_sts/qcloud-sts-sdk": "3.0.*"
    }
}

添加好了后命令提示符到后端根目录下执行  composer update

 安装好了后新建一个文件,或者控制器,弄好了,试一试访问有没有问题哈,没问题的话响应是这样的

{"code":10001,"status":"success","data":{"expiredTime":1651332681,"expiration":"2022-04-30T15:31:21Z","credentials":{"sessionToken":"xxxxxxxxxxxxxxxxxxx","tmpSecretKey":"xxxxxxxxxxx="},"requestId":"xxxxxxxxxx","startTime":xxxxxxx}}

{"code":10001,"status":"success","data":{ 这一节是我自己加上去的

下面是控制器的代码

<?php

declare(strict_types=1);

namespace app\controller;

use QCloud\COSSTS\Sts;

class Cos
{
    /**
     * 获取临时密钥,计算签名
     *
     * @return \think\Response
     */
    public function index()
    {
        $sts = new Sts();
        $config = array(
            'url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致
            'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
            'proxy' => '',
            'secretId' => "XXXXXXXXXXXXXXXXXX", // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
            'secretKey' => "XXXXXXXXXXXXXXXXXX", // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
            'bucket' => "储存桶名称", // 换成你的 bucket
            'region' => "储存桶地区", // 换成 bucket 所在园区
            'durationSeconds' => 1800, // 密钥有效期
            'allowPrefix' => '*', // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: 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'
            )
        );

        // 获取临时密钥,计算签名
        $tempKeys = $sts->getTempKeys($config);
        return success($tempKeys);
        //这个success()是我自己弄的个方法写在公共方法里的
        //就像这样
        //function success($data)
        //{
        //   return json(['code' => 10001, 'status' => 'success', 'data' => $data]);
        //}
    }
}

下一步流程

注意,我是使用的子账号,所以我有在腾讯云COS控制台配置权限,

 访问管理新建一个子用户,然后点击授权,搜索cos的,相关的权限都勾选上基本不会出问题。

添加的时候应该会给你一个secretId和secretKey,记录下来,需要写入到上面的php控制器文件里的

然后储存桶管理添加配置跨域规则跟防盗链哈 

 储存桶管理里面配置子账户权限

 存储桶访问权限Policy权限设置这样设置就行了。

自助诊断地址 记住这个地址,后面会用到。

然后这个后端这一块儿配置完了。

继续去配置前端的。

因为用了axios嘛,所以先给前端配置个API 

你们用的啥方法做http请求的就按自己的来哈,只要是个请求就行。

这个是向后端请求临时密钥的接口,记得后端加个权限验证,登录了再给访问接口。

cos.js文件,

import request from '@/utils/request'

export function getCos(params) {
  return request({
    url: '/Cos',
    method: 'get',
    params
  })
}

然后接口写好了就要访问嘛。

新建一个js咯,这个里面引入了安装的sdk,跟上面的api,我这个文件放在路由的文件夹里面的,你看自个放哪儿都行

// 前端
// cos.js
import COS from 'cos-js-sdk-v5';
import {
  getCos
} from '@/api/cos';
// 初始化实例
export const cos = new COS({
  // getAuthorization 必选参数
  getAuthorization: function(options, callback) {
    getCos().then(res => {
      if (res.code == 10001) {
        var credentials = res.data && res.data.credentials;
        if (!res || !credentials) return console.error('credentials invalid');
        callback({
          TmpSecretId: credentials.tmpSecretId,
          TmpSecretKey: credentials.tmpSecretKey,
          XCosSecurityToken: credentials.sessionToken,
          // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
          StartTime: res.data.startTime, // 时间戳,单位秒,如:1580000000
          ExpiredTime: res.data.expiredTime, // 时间戳,单位秒,如:1580000900
          // ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
        });
      }
    })
  }
});

上面这个代码是我改过的,能用,然后再放一段官方的代码你们看需求用的这个还是官方这个。

var COS = require('cos-js-sdk-v5');
var cos = new COS({
    // getAuthorization 必选参数
    getAuthorization: function (options, callback) {
        // 异步获取临时密钥
        // 服务端 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

        var url = 'http://example.com/server/sts.php'; // url替换成您自己的后端服务
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.onload = function (e) {
            try {
                var data = JSON.parse(e.target.responseText);
                var 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();
    }
});

,然后获取密钥的OK了,那肯定要发送了嘛,随便做一个点击事件写个方法测试下。

//先引入上面的文件哈
  import {
    cos
  } from '@/router/cos'
//然后写个方法里面这样的
cos.putObject({
   Bucket: 'edu-1255457652',
     /* 必须 */
    Region: 'ap-chengdu',
     /* 存储桶所在地域,必须字段 */
     Key: '1.jpg',
     // 上传名称
    body:'XXXX'
    //文件上传对象或字符串
   }, function(data) {
            console.log(data);
    });

我这里是成功的哈

 既然能上传了,那就封装下。

跟获取临时密钥的放一起不放一起都行

//引入COS获取密钥
import {
  cos
} from '@/router/cos'
// 导出上传方法
export function uploadFile(file, keys) {
  const key = 'Image/' + keys; // Key: 对象键(Object 的名称),对象在存储桶中的唯一标识
  let res = Promise
    .all([cos]) //获取临时密钥
    .then((res) => {
      return new Promise((resolve, reject) => {
        cos.putObject({
          Bucket: 'xxxxxxxxxx',
          /* 后端返回的桶名称,我这里没有从后端返回 */
          Region: 'xxxxxxxxxxx',
          /* 桶的对应地区 */
          Key: key,
          /* 文件名,也是文件在桶里唯一的标识 */
          StorageClass: 'STANDARD',
          Body: file, // 上传文件对象
          onProgress: function(progressData) {
            // console.log(JSON.stringify(progressData));
          }
        }, function(err, data) { //回调函数
          if (!err) {
            //成功返回data对象
            resolve(data);
          } else {
            //失败返回error信息
            reject(err);
          }
        });
      })
    })
  return res
}

OK了,就这样,然后使用的话

  import {
    uploadFile
  } from '@/router/update'
//引入是必须的

//使用
uploadFile('1.text,我是名称,也可以是md5加密名字加上.png/.jpg啥的','我是内容,也可以是视频,图片对象啥的,这个地方一般字符串或者对象形式').then(res=>{
            console.log(res);
          })

到这儿就结束了,备忘一下。调试中出啥问题,都可以去自助诊断查询,实在不行提交工单,等待大佬技术支持。

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Vue3.0中使用ant-design-vue上传文件,需要先安装ant-design-vue和axios模块: ```bash npm install ant-design-vue axios --save ``` 然后在需要使用上传组件的页面中,引入ant-design-vue和axios模块: ```javascript import { Upload, Button } from 'ant-design-vue'; import axios from 'axios'; ``` 然后在页面中,添加上传组件: ```html <template> <div> <upload :action="uploadUrl" :headers="headers" :showUploadList="false" :beforeUpload="beforeUpload" :onSuccess="onSuccess" :onError="onError" > <button> <a-button> <a-icon type="upload" /> Click to Upload </a-button> </button> </upload> </div> </template> ``` 其中,`uploadUrl`是上传文件的接口地址,`headers`是上传文件时需要携带的请求头,`beforeUpload`是上传文件前的校验函数,`onSuccess`和`onError`分别是上传成功和上传失败的回调函数。 在页面的`script`中,需要定义这些属性的值以及`beforeUpload`、`onSuccess`、`onError`函数的实现: ```javascript export default { name: 'UploadPage', components: { Upload, Button }, data() { return { uploadUrl: '/api/upload', headers: { Authorization: 'Bearer ' + localStorage.getItem('token') } }; }, methods: { beforeUpload(file) { const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJpgOrPng) { this.$message.error('You can only upload JPG/PNG file!'); return false; } const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { this.$message.error('Image must smaller than 2MB!'); return false; } return true; }, onSuccess(response, file) { this.$message.success('Upload successfully!'); }, onError(error, response, file) { this.$message.error('Upload error!'); } } }; ``` 其中,`beforeUpload`函数用来进行文件类型和大小的校验,`onSuccess`和`onError`函数用来处理上传成功和上传失败的情况。 最后,在页面的`style`中,可以添加一些样式来美化上传按钮: ```css button { margin-top: 16px; } button .ant-btn { width: 100%; } button .anticon-upload { margin-right: 8px; } ``` 这样,就可以在Vue3.0中使用ant-design-vue上传文件了。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值