初学者123
初学者123
  • 发布:2021-02-02 19:14
  • 更新:2022-03-28 11:49
  • 阅读:6551

uniapp前端图片和视频直传华为云OBS记录

分类:uni-app

uniapp 官方合作的云存储是阿里云和腾讯云,但我们公司选的云存储服务恰好都不是这两家,是华为云 OBS。网上搜了多次,没有能成功的案例分享。但是,考虑到网上关于华为云性能优异的测评报告,以及我对华为这家公司的好感,我还是想努力把这条路走通。因此,走上了坚苦的踩坑之路。

但大家不必重复这个踩坑经历了,我直接上拿走即用的代码。

技术路线确定:

  1. 前端产生签名前端直传华为云OBS:好处是不经过自家服务器周转,减少一个环节,上传速度更快。坏处:前端产生签名的过程中,会将 AK,SK 等核心账号信息暴露,是极其危险的。
  2. 后端签名前端获取后直传华为云OBS:好处同上,而且由于是后端生成签名,前端获取有时效性的签名后直传云端,因此没有泄露核心账号信息的风险。

我选择第二条路线。以下是上传视频文件的步骤(图片上传相似,多文件在上传前增加一个循环而已。下面不只是前端代码,也包括必要的后端代码):

1.后端生成上传文件到OBS 的签名(PHP)的代码:
在做这一步之前,让后台技术同事先在服务器目录下安装 OBS的 PHP SKD,这一步有详细文档,此处忽略。


        $object = $this->input->post('file_name')?:''; //文件名  
        $file_type = $this->input->post('file_type')?: ''; //文件类型  
        $obsClient = new ObsClient ( [   
              'key' => '***',           //OBS 中的 AK  
              'secret' => '***',      //OBS 中的 SK  
              'endpoint' => 'https://obs.cn-north-4.myhuaweicloud.com', //注意实际的终点可能不同  
              'signature' => 'obs',  
        ] );  

        // URL有效期,3600秒  
        $expires = 3600;  

        // 上传对象  
          $resp = $obsClient->createPostSignature( [   
              'Bucket' => '***',    //你自己的桶名(bucket)  
              'Key' => $object,  
              'Expires' => $expires,  
              'FormParams' => [  
                     'x-obs-acl' => 'public-read',  
                     'content-type' => $file_type,  
              ]  
        ] );  
        // printf($resp);  
        $data['Accesskeyid'] = '***';  //AK  
        $data['Policy'] = $resp['Policy'];  
        $data['Signature'] = $resp['Signature'];  
        echo json_encode($data);  

    } ```  

2. 前端选择视频文件,生成必要信息:
```select_video(){  
                var _this = this;  
                uni.chooseVideo({  
                    maxDuration: 60,  //拍摄视频最长拍摄时间,单位秒  
                    count:1, //上传视频的数量  
                    sourceType:['camera','album'],  
                    success: (res) => {  
                        console.log(res)  
                        _this.video_src = res.tempFilePath;  
                        let index1 = res.tempFilePath.lastIndexOf('/');    
                        let index2 = res.tempFilePath.lastIndexOf('.');  
                        _this.file_name = res.tempFilePath.substring(index1+1,res.tempFilePath.length);   //获取文件名  
                        _this.file_type = res.tempFilePath.substring(index2+1, res.tempFilePath.length); // 获取文件后缀名,即文件类型  
                        _this.key = 'video/' + _this.file_name;  
                        console.log(_this.file_name)  
                        _this.is_video = 1;  
                    },  
                })  
            }, ```  

3. 前端获取上传文件的签名并直传 OBS(一步完成):  
可以写在当前页面,也可以封装成公共方法,建议封装。  

 ``` function get_obs_signature(file_path, file_name, file_type){  
    console.log(file_name)  
    return new Promise((resolve, reject)=>{  
        uni.request({  
            url: '***',    //PHP获取签名的接口路径  
            method: 'POST',  
            header:{  
                'Content-Type': 'application/x-www-form-urlencoded'  
            },  
            data: {  
                file_name: file_name,  
                file_type: file_type  
            },  
            success: (res) => {  
                console.log(res.data)  
                resolve(res.data)  
            }  
        })  
    }).then(res=>{  
        let policy = res.Policy;  
        let signature = res.Signature;  
        let ak = res.Accesskeyid;  
        console.log(policy)  
        uni.uploadFile({  
            url: 'https://***.obs.cn-north-4.myhuaweicloud.com',  //用你自己的 bucket 名替换星号  
            filePath: file_path,  
            name: 'file',  
            formData: {  
              'key': file_name,  
              'AccessKeyId': ak,  
              'Policy': policy,  
              'x-obs-acl': 'public-read',  
              'content-type': file_type,  
              'Signature': signature  
            },  
            success:(res)=>{  
                console.log(res);  
            }  
        })  
    }) ```   

4. 获取上传后的文件路径:  
OBS 默认不返回上传成功的路径,那该怎么办?其实很简单,存储在 OBS 的文件都有规律,通过以下方法可以拼接:  
obs_url = 'https://***.obs.cn-north-4.myhuaweicloud.com/' + _this.key;  //用你自己的 bucket 名替换星号  
0 关注 分享

要回复文章请先登录注册

2***@qq.com

2***@qq.com

能不能说一下policy怎么生成的?
2022-03-28 11:49
1***@qq.com

1***@qq.com

回复 l***@126.com :
去掉了,又报405
2022-02-18 17:30
2***@qq.com

2***@qq.com

回复 l***@126.com :
请问搞定了吗
2021-09-23 10:33
l***@126.com

l***@126.com

'x-obs-acl': 'public-read',
'content-type': file_type,
我这试了试,这两行去掉,才可以。不然403
2021-03-26 10:56
l***@126.com

l***@126.com

大佬你好,能否直接在客户端 获取签名的相关信息呢?
如:
let policy = res.Policy;
let signature = res.Signature;
let ak = res.Accesskeyid;
这几个值服务端可以,客户端可以直接获取吗? 如你技术路线方式1:前端产生签名前端直传华为云OBS
2021-03-25 09:30