微信小程序/网站 上传图片到腾讯云COS

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序/网站 上传图片到腾讯云COS相关的知识,希望对你有一定的参考价值。

COS简介: 腾讯云提供的一种对象存储服务,供开发者存储海量文件的分布式存储服务。可以将自己开发的应用的存储部分全部接入COS的存储桶中,有效减少应用服务器的带宽,请求等。个人也可以通过腾讯云账号免费使用COS6个月,https://cloud.tencent.com/product/cos

整体流程简介: 

1. 前端引入cos的SDK文件

2. 监听上传控件,并在图片加载至网页临时流中发起签名请求

3.后端根据上传的请求方式和路径参数返回签名Authorization和token XCosSecurityToken

4.前端再根据返回的参数和SDK以3的请求方式上传图片。

PHP签名返回流程:

1.在腾讯云的建好存储桶并配置CORS规则https://cloud.tencent.com/document/product/436/11459

2.在平台上拿到Bucket(存储桶),Region(地域),SecretId,SecretKey等参数。

3.使用(SecretId,Timestamp…)参数进行签名通过腾讯云的接口获取临时密钥,返回给前端的token也在临时密钥中

4.根据前端传的(上传请求方式,路径)和临时密钥进行签名(前端上传所使用的)并返回。

一、PHP获取签名部分(tp5)

<?php
// +----------------------------------------------------------------------
// | When work is a pleasure, life is a joy!
// +----------------------------------------------------------------------
// | User: 傅超|  Email:1741108471@qq.com | Time:2018/04/21 17:55
// +----------------------------------------------------------------------
// | TITLE: 小程序接口
// +----------------------------------------------------------------------

namespace app\\v1\\controller;

use think\\Request;
use think\\Db;
use app\\v1\\location\\Location;
use think\\Cache;
use \\app\\v1\\auth\\AccessToken;
use \\app\\v1\\extend\\Loginlog;

// 返回数据给前端
header(\'Content-Type: application/json\');
header(\'Allow-Control-Allow-Origin: *\');       // 这里修改允许跨域访问的网站
// header(\'Allow-Control-Allow-Origin: http://127.0.0.1\');       // 这里修改允许跨域访问的网站
//header(\'Allow-Control-Allow-Origin: http://mer.runmoneyin.com\'); // 这里修改允许跨域访问的网站
header(\'Allow-Control-Allow-Headers: origin,accept,content-type\');


/**
 * Class  Cosauth
 * @title 获取腾讯云cos签名接口
 * @url   http://119.29.10.64/v1/Cosauth
 * @desc  小程序接口包含:获取上传图片签名
 * @version 1.0
 */
class Cosauth extends Base
{
    // 附加方法
    protected $extraActionList = [\'getCosAuth\', \'getCosAuth\'];

    // 跳过验证方法
    protected $skipAuthActionList = [\'getCosAuth\', \'getCosAuthEsay\'];

    // appid
    //protected $appid = \'wx4c0e1852239664b4\';

    // cos配置参数
    protected $config = array(
        \'Url\'         => \'https://sts.api.qcloud.com/v2/index.php\',
        \'Domain\'      => \'sts.api.qcloud.com\',   
        \'Proxy\'       => \'\',
        \'SecretId\'    => \'AK********************BLK9nF5dZL\', // 固定密钥
        \'SecretKey\'   => \'jHj5G*********************IUcqJu\',     // 固定密钥
        \'Bucket\'      => \'activity-1255484416\',               // 存储桶
        \'Region\'      => \'ap-guangzhou\',
        \'AllowPrefix\' => \'*\', // 这里改成允许的路径前缀,这里可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg
    );

    /**
     * @title 获取签名入口
     * http://119.29.10.64/v1/Cosauth/getCosAuth
     */
    public function getCosAuth() {
        // $data[\'say\'] = \'hello\';
        // echo json_encode($data);
        // die;

        // 缓存临时密钥
        if (!isset($_SESSION[\'tempKeysCache\'])) {
            $_SESSION[\'tempKeysCache\'] = array(
                \'policyStr\' => \'\',
                \'expiredTime\' => 0
            );
        }

        // 获取前端过来的参数
        // $method = isset($_GET[\'method\']) ? $_GET[\'method\'] : \'get\';
        // $pathname = isset($_GET[\'pathname\']) ? $_GET[\'pathname\'] : \'/\';
        
        $method   = input(\'method\') ? input(\'method\') : \'post\';
        $pathname = input(\'pathname\') ? input(\'pathname\') : \'/\';
        $callback = input(\'callback\') ? input(\'callback\') : \'\';    // 前端跨域的jsonp参数(可忽略)

        // 获取临时密钥,计算签名
        $tempKeys = $this->getTempKeys();

        if ($tempKeys && $tempKeys[\'credentials\']) {

            // $datas = $this->getAuthorization($tempKeys, $method, $pathname);
            // echo json_encode($datas);
            // die;
            $data = array(
                \'Authorization\' => $this->getAuthorization($tempKeys, $method, $pathname),
                \'XCosSecurityToken\' => $tempKeys[\'credentials\'][\'sessionToken\'],
            );

        } else {
            $data = array(\'error\'=> $tempKeys);
        }

        //echo $callback . \'(\' . json_encode($data) . \')\';     // 通过回调返回给其他域(可忽略)
        echo json_encode($data);     // 正常写法的返回
        die;
    }


    // json 转 query string
    public function json2str($obj, $notEncode = false) {
        ksort($obj);
        $arr = array();
        foreach ($obj as $key => $val) {
            !$notEncode && ($val = urlencode($val));
            array_push($arr, $key . \'=\' . $val);
        }
        return join(\'&\', $arr);
    }

    // 计算临时密钥用的签名
    public function getSignature($opt, $key, $method) {
        //global $config;
        $formatString = $method . $this->config[\'Domain\'] . \'/v2/index.php?\' . $this->json2str($opt, 1);
        $sign = hash_hmac(\'sha1\', $formatString, $key);
        $sign = base64_encode(hex2bin($sign));
        return $sign;
    }

    // 获取临时密钥
    public function getTempKeys() {

        //global $config;

        // 判断是否修改了 AllowPrefix
        if ($this->config[\'AllowPrefix\'] === \'_ALLOW_DIR_/*\') {
            return array(\'error\'=> \'请修改 AllowPrefix 配置项,指定允许上传的路径前缀\');
        }

        $ShortBucketName = substr($this->config[\'Bucket\'],0, strripos($this->config[\'Bucket\'], \'-\'));
        $AppId = substr($this->config[\'Bucket\'], 1 + strripos($this->config[\'Bucket\'], \'-\'));
        $policy = array(
            \'version\'=> \'2.0\',
            \'statement\'=> array(
                array(
                    \'action\'=> array(
                        // 简单文件操作
                        \'name/cos:PutObject\',
                        \'name/cos:PostObject\',
                        \'name/cos:AppendObject\',
                        \'name/cos:GetObject\',
                        \'name/cos:HeadObject\',
                        \'name/cos:OptionsObject\',
                        \'name/cos:PutObjectCopy\',
                        \'name/cos:PostObjectRestore\',
                        // 分片上传操作
                        \'name/cos:InitiateMultipartUpload\',
                        \'name/cos:ListMultipartUploads\',
                        \'name/cos:ListParts\',
                        \'name/cos:UploadPart\',
                        \'name/cos:CompleteMultipartUpload\',
                        \'name/cos:AbortMultipartUpload\',
                    ),
                    \'effect\'=> \'allow\',
                    \'principal\'=> array(\'qcs\'=> array(\'*\')),
                    \'resource\'=> array(
                        \'qcs::cos:\' . $this->config[\'Region\'] . \':uid/\' . $AppId . \':prefix//\' . $AppId . \'/\' . $ShortBucketName . \'/\',
                        \'qcs::cos:\' . $this->config[\'Region\'] . \':uid/\' . $AppId . \':prefix//\' . $AppId . \'/\' . $ShortBucketName . \'/\' . $this->config[\'AllowPrefix\']
                    )
                )
            )
        );

        $policyStr = str_replace(\'\\\\/\', \'/\', json_encode($policy));
        $Action = \'GetFederationToken\';
        $Nonce = rand(10000, 20000);
        $Timestamp = time() - 1;
        $Method = \'GET\';

        $params = array(
            \'Action\'=> $Action,
            \'Nonce\'=> $Nonce,
            \'Region\'=> \'\',
            \'SecretId\'=> $this->config[\'SecretId\'],
            \'Timestamp\'=> $Timestamp,
            \'durationSeconds\'=> 7200,
            \'name\'=> \'\',
            \'policy\'=> $policyStr
        );
        $params[\'Signature\'] = urlencode($this->getSignature($params, $this->config[\'SecretKey\'], $Method));

        $url = $this->config[\'Url\'] . \'?\' . $this->json2str($params, 1);
        $ch = curl_init($url);
        $this->config[\'Proxy\'] && curl_setopt($ch, CURLOPT_PROXY, $this->config[\'Proxy\']);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        if(curl_errno($ch)) $result = curl_error($ch);
        curl_close($ch);

        $result = json_decode($result, 1);
        $_SESSION[\'tempKeysCache\'] = $result[\'data\'];
        $_SESSION[\'tempKeysCache\'][\'policyStr\'] = $policyStr;

        return $result[\'data\'];
    }

    // 计算 COS API 请求用的签名
    public function getAuthorization($keys, $method, $pathname)
    {

        // 获取个人 API 密钥 https://console.qcloud.com/capi
        $SecretId = $keys[\'credentials\'][\'tmpSecretId\'];
        $SecretKey = $keys[\'credentials\'][\'tmpSecretKey\'];

        // 整理参数
        $query = array();
        $headers = array();
        $method = strtolower($method ? $method : \'get\');
        $pathname = $pathname ? $pathname : \'/\';
        substr($pathname, 0, 1) != \'/\' && ($pathname = \'/\' . $pathname);

        // 工具方法
        function getObjectKeys($obj)
        {
            $list = array_keys($obj);
            sort($list);
            return $list;
        }

        function obj2str($obj)
        {
            $list = array();
            $keyList = getObjectKeys($obj);
            $len = count($keyList);
            for ($i = 0; $i < $len; $i++) {
                $key = $keyList[$i];
                $val = $obj[$key] ? $obj[$key] : \'\';
                $key = strtolower($key);
                $list[] = rawurlencode($key) . \'=\' . rawurlencode($val);
            }
            return implode(\'&\', $list);
        }

        // 签名有效起止时间
        $now = time() - 1;
        $expired = $now + 3600; // 签名过期时刻,600 秒后

        // 要用到的 Authorization 参数列表
        $qSignAlgorithm = \'sha1\';
        $qAk = $SecretId;
        $qSignTime = $now . \';\' . $expired;
        $qKeyTime = $now . \';\' . $expired;
        $qHeaderList = strtolower(implode(\';\', getObjectKeys($headers)));
        $qUrlParamList = strtolower(implode(\';\', getObjectKeys($query)));


        // 签名算法说明文档:https://www.qcloud.com/document/product/436/7778
        // 步骤一:计算 SignKey
        $signKey = hash_hmac("sha1", $qKeyTime, $SecretKey);

        // 步骤二:构成 FormatString
        $formatString = implode("\\n", array(strtolower($method), $pathname, obj2str($query), obj2str($headers), \'\'));

        // 自定义头部(暂时关闭)
        // header(\'x-test-method\', $method);
        // header(\'x-test-pathname\', $pathname);

        // 步骤三:计算 StringToSign
        $stringToSign = implode("\\n", array(\'sha1\', $qSignTime, sha1($formatString), \'\'));

        // 步骤四:计算 Signature
        $qSignature = hash_hmac(\'sha1\', $stringToSign, $signKey);

        // 步骤五:构造 Authorization
        $authorization = implode(\'&\', array(
            \'q-sign-algorithm=\' . $qSignAlgorithm,
            \'q-ak=\' . $qAk,
            \'q-sign-time=\' . $qSignTime,
            \'q-key-time=\' . $qKeyTime,
            \'q-header-list=\' . $qHeaderList,
            \'q-url-param-list=\' . $qUrlParamList,
            \'q-signature=\' . $qSignature
        ));

        return $authorization;
    }

 /*********************************************************************************************************************************************/

//     // cos配置参数
//     protected $config = array(
//         \'Url\'         => \'https://sts.api.qcloud.com/v2/index.php\',
//         \'Domain\'      => \'sts.api.qcloud.com\',   
//         \'Proxy\'       => \'\',
//         \'SecretId\'    => \'AKIDwqbCewU2ZxABC3QDWp1EWrBLK9nF5dZL\', // 固定密钥
//         \'SecretKey\'   => \'jHj5GIAvV8eFk3B8tSwKXYO4f0IUcqJu\',     // 固定密钥
//         \'Bucket\'      => \'xcx-1255484416\',
//         \'Region\'      => \'ap-guangzhou\',
//         \'AllowPrefix\' => \'*\', // 这里改成允许的路径前缀,这里可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg
//     );
//     // $config = array(
//     //     \'Url\' => \'https://sts.api.qcloud.com/v2/index.php\',
//     //     \'Domain\' => \'sts.api.qcloud.com\',
//     //     \'Proxy\' => \'\',
//     //     \'SecretId\' => \'AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\', // 固定密钥
//     //     \'SecretKey\' => \'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\', // 固定密钥
//     //     \'Bucket\' => \'test-1250000000\',
//     //     \'Region\' => \'ap-guangzhou\',
//     //     \'AllowPrefix\' => \'_ALLOW_DIR_/*\', // 必填,这里改成允许的路径前缀,这里可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg
//     // );
//     // json 转 query string
//     function json2str($obj, $notEncode = false) 
//     {
//         ksort($obj);
//         $arr = array();
//         foreach ($obj as $key => $val) {
//             !$notEncode && ($val = urlencode($val));
//             array_push($arr, $key . \'=\' . $val);
//         }
//         return join(\'&\', $arr);
//     }

//     // 计算临时密钥用的签名
//     function getSignature($opt, $key, $method) 
//     {

//         $formatString = $method . $this->config[\'Domain\'] . \'/v2/index.php?\' . self::json2str($opt, 1);
//         $sign = hash_hmac(\'sha1\', $formatString, $key);
//         $sign = base64_encode(hex2bin($sign));
//         return $sign;
//     }

//     // 获取临时密钥
//     function getTempKeys() 
//     {
//         // 判断是否修改了 AllowPrefix
//         if ($this->config[\'AllowPrefix\'] === \'_ALLOW_DIR_/*\') {
//             return array(\'error\'=> \'请修改 AllowPrefix 配置项,指定允许上传的路径前缀\');
//         }
// // dump($this->config);
//         $ShortBucketName = substr($this->config[\'Bucket\'],0, strripos($this->config[\'Bucket\'], \'-\'));
//         $AppId = substr($this->config[\'Bucket\'], 1 + strripos($this->config[\'Bucket\'], \'-\'));
//         $policy = array(
//             \'version\'=> \'2.0\',
//             \'statement\'=> array(
//                 array(
//                     \'action\'=> array(
//                         // // 这里可以从临时密钥的权限上控制前端允许的操作
//                           \'name/cos:*\', // 这样写可以包含下面所有权限
//                         // // 列出所有允许的操作
//                         // // ACL 读写
//                         // \'name/cos:GetBucketACL\',
//                         // \'name/cos:PutBucketACL\',
//                         // \'name/cos:GetObjectACL\',
//                         // \'name/cos:PutObjectACL\',
//                         // // 简单 Bucket 操作
//                         // \'name/cos:PutBucket\',
//                         // \'name/cos:HeadBucket\',
//                         // \'name/cos:GetBucket\',
//                         // \'name/cos:DeleteBucket\',
//                         // \'name/cos:GetBucketLocation\',
//                         // // Versioning
//                         // \'name/cos:PutBucketVersioning\',
//                         // \'name/cos:GetBucketVersioning\',
//                         // // CORS
//                         // \'name/cos:PutBucketCORS\',
//                         // \'name/cos:GetBucketCORS\',
//                         // \'name/cos:DeleteBucketCORS\',
//                         // // Lifecycle
//                         // \'name/cos:PutBucketLifecycle\',
//                         // \'name/cos:GetBucketLifecycle\',
//                         // \'name/cos:DeleteBucketLifecycle\',
//                         // // Replication
//                         // \'name/cos:PutBucketReplication\',
//                         // \'name/cos:GetBucketReplication\',
//                         // \'name/cos:DeleteBucketReplication\',
//                         // // 删除文件
//                         // \'name/cos:DeleteMultipleObject\',
//                         // \'name/cos:DeleteObject\',
//                         // 简单文件操作
//                         \'name/cos:PutObject\',
//                         \'name/cos:PostObject\',
//                         \'name/cos:AppendObject\',
//                         \'name/cos:GetObject\',
//                         \'name/cos:HeadObject\',
//                         \'name/cos:OptionsObject\',
//                         \'name/cos:PutObjectCopy\',
//                         \'name/cos:PostObjectRestore\',
//                         // 分片上传操作
//                         \'name/cos:InitiateMultipartUpload\',
//                         \'name/cos:ListMultipartUploads\',
//                         \'name/cos:ListParts\',
//                         \'name/cos:UploadPart\',
//                         \'name/cos:CompleteMultipartUpload\',
//                         \'name/cos:AbortMultipartUpload\',
//                     ),
//                     \'effect\'=> \'allow\',
//                     \'principal\'=> array(\'qcs\'=> array(\'*\')),
//                     \'resource\'=> array(
//                         \'qcs::cos:\' . $this->config[\'Region\'] . \':uid/\' . $AppId . \':prefix//\' . $AppId . \'/\' . $ShortBucketName . \'/\',
//                         \'qcs::cos:\' . $this->config[\'Region\'] . \':uid/\' . $AppId . \':prefix//\' . $AppId . \'/\' . $ShortBucketName . \'/\' . $this->config[\'AllowPrefix\']
//                     )
//                 )
//             )
//         );

//         $policyStr = str_replace(\'\\\\/\', \'/\', json_encode($policy));
//         $Action = \'GetFederationToken\';
//         $Nonce = rand(10000, 20000);
//         $Timestamp = time() - 1;
//         $Method = \'GET\';
//         $params = array(
//             \'Action\'=> $Action,
//             \'Nonce\'=> $Nonce,
//             \'Region\'=> \'\',
//             \'SecretId\'=> $this->config[\'SecretId\'],
//             \'Timestamp\'=> $Timestamp,
//             \'durationSeconds\'=> 7200,
//             \'name\'=> \'\',
//             \'policy\'=> $policyStr
//         );

//         $params[\'Signature\'] = urlencode(self::getSignature($params, $this->config[\'SecretKey\'], $Method));
//         $url = $this->config[\'Url\'] . \'?\' . self::json2str($params, 1);
//         $ch = curl_init($url);
//         $this->config[\'Proxy\'] && curl_setopt($ch, CURLOPT_PROXY, $this->config[\'Proxy\']);
//         curl_setopt($ch, CURLOPT_HEADER, 0);
//         curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
//         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//         $result = curl_exec($ch);
//         if(curl_errno($ch)) $result = curl_error($ch);
//         curl_close($ch);
//         $result = json_decode($result, 1);
//         return $result[\'data\'];
//     }

//     public function getCosAuth() 
//     {
//         // 获取临时密钥,计算签名
//         $tempKeys = self::getTempKeys();
//         // 返回数据给前端
//         header(\'Content-Type: application/json\');
//         header(\'Allow-Control-Allow-Origin: *\'); // 这里修改允许跨域访问的网站
//         header(\'Allow-Control-Allow-Headers: origin,accept,content-type\');

//         echo json_encode($tempKeys);
//     }
}

 

二、javascript上传图片部分

首先去腾旭云下载cos-js-sdk-v5.min.js并引入页面,这里只展示实现部分

// 图片上传监听事件
function uploadConver(_this,event) {

	for(var i = 0;i<event.target.files.length;i++) {
        var files = event.target.files[i];

        if (!files) {
			tipPopup(\'未选择上传文件\',1100,4);
			return;
		}

		files && uploadFile(files, function (err, data) {

			if(data) {
				$("#preImg").html("").append(\'<img src="\'+data.url+\'" width="200px"/>\');
				//$("#conver").val(data.url);
				console.log(data);
			}else {
				console.log(err);
			}

			//console.log(err || data);
			//document.getElementById(\'msg\').innerText = err ? err : (\'上传成功,ETag=\' + data.ETag);
		});
        //uploadFileToOss(file);
        //console.log(file);
    }
}

// 异步请求上传签名
var getAuthorization = function (options, callback) {
        
     var xhr = new XMLHttpRequest();
     xhr.open(\'GET\', url, true);
     xhr.onload = function (e) {
         var AuthData;
         try {
             AuthData = JSON.parse(xhr.responseText)
         } catch (e) {}
         if (AuthData && AuthData.Authorization) {
             callback(null, {
                 Authorization: AuthData.Authorization,
                 XCosSecurityToken: AuthData.XCosSecurityToken,
             });
            
         } else {
         	// alert(123);
             console.error(AuthData);
             callback(\'获取签名出错\');
         }
     };
     xhr.onerror = function (e) {
         callback(\'获取签名出错\');
     };
     xhr.send();
};

// 上传文件(真正上传到COS)
var uploadFile = function (file, callback) {

	if(file.size>1024*1024*2) {		// 限制图片大小2M
		layer.open({content: \'上传的图片不能超过 2MB\',skin: \'msg\',time: 3 });
		//tipPopup("上传的图片不能超过 2MB",1100,3);
		return;
	}

	if(file.type != \'image/jpeg\' && file.type != \'image/png\' && file.type != \'image/gif\') {		// 限制图片格式
		layer.open({content: \'上传图片的格式不正确\',skin: \'msg\',time: 3 });
		//tipPopup("上传图片的格式不正确",1100,3);
		return;
	}

	// 检测文件名不能含有中文汉字
	if(escape(file.name).indexOf(\'%u\') != -1) {
		layer.open({content: \'上传的文件名有中文,请重新上传\',skin: \'msg\',time: 3 });
		return;
	}

	var dirBase = \'temp2018/\';
	var myDate = new Date();
	var reg = new RegExp( \'/\' , "g" );

	// var specilReg = /[@#\\$\\!()%-~+\\^&\\s*]+/g;;	// 过滤文件名的特殊字符
	// var fileName = file.name.replace(specilReg,\'\');
	var files = (myDate.toLocaleDateString()).replace(reg,"")+\'/\'+myDate.getTime()+\'_\'+parseInt(Math.random()*100000)+\'_\'+file.name;
    var Key = dirBase+ files; // 这里指定上传目录和文件名
    
    // 执行获取签名函数,拿到签名通过回调上传
    getAuthorization({Method: \'POST\', Key: Key}, function (err, info) {
    	
        var fd = new FormData();
        fd.append(\'key\', Key);
        fd.append(\'Signature\', info.Authorization);
        fd.append(\'Content-Type\', \'\');
        info.XCosSecurityToken && fd.append(\'x-cos-security-token\', info.XCosSecurityToken);
        fd.append(\'file\', file);
        var url = prefix;
        var xhr = new XMLHttpRequest();
        xhr.open(\'POST\', url, true);
        xhr.onload = function () {
            if (Math.floor(xhr.status / 100) === 2) {
                var ETag = xhr.getResponseHeader(\'etag\');
                callback(null, {url: url+Key, ETag: ETag});
            }else {
                callback(\'文件 \' + Key + \' 上传失败,状态码:\' + xhr.status);
            }
        };
        xhr.onerror = function () {
            callback(\'文件 \' + Key + \' 上传失败,请检查是否没配置 CORS 跨域规则\');
        };
        $("#preImg").html("").append(\'<span style="color:red">上传中……</span>\');
        xhr.send(fd);

    });
};

----------------------------------------------------------------------------------------------------------

三、微信小程序上传方式

这里小程序就演示直接自己生成签名,然后通过cos的SDK提供的函数上传。

1.config.js 单独配置

var config = {
   Bucket: \'busin-1256537792\',//存储桶
    Region: \'ap-guangzhou\',//地域
    SecretId: \'AKIDTtR************XiiW8nLLlp39yl4LW\', 
    SecretKey: \'hslO1YxFNJ5lGh0yR7c4Qemi8VhPRhmf\', //replace with yours
}

module.exports = config

2.实现上传功能

/*
*author: fuchao
*date: 2018-04-27
*desc: 小程序本地签名上传图片到腾讯云cos
*个人公众号: ZEROFC_DEV
**/

// 同样需要先引入COS的SDK,和配置文件
var COS = require(\'../../lib/cos-wx-sdk-v5\');
var config = require(\'./config\');

// 实例COS
var cos = new COS({
    getAuthorization: function (params, callback) {	//获取签名
        var authorization = COS.getAuthorization({
            SecretId: config.SecretId,
            SecretKey: config.SecretKey,
            Method: params.Method,
            Key: params.Key
        });
        callback(authorization);
    }
});

Page({
  data: {
    list: [],
  },
  simpleUpload: function() {
    // 选择文件
    wx.chooseImage({
      count: 4, // 默认9
      sizeType: [\'original\', \'compressed\'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: [\'album\', \'camera\'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        var filePath = res.tempFilePaths[0]
        var Key = filePath.substr(filePath.lastIndexOf(\'/\') + 1); // 这里指定上传的文件名
        var dateObj = new Date();
        var timestamp = dateObj.getTime();
        var nowDate = dateObj.toLocaleDateString();
        var formatDate = nowDate.replace(/\\//g,"-");  // 格式斜杠日期
        console.log(formatDate);
        var newKey = formatDate + \'/\' + timestamp+Key;   // cos上定义目录
        var tempObj = {};
        tempObj.imgLocation = \'https://\' + config.Bucket + \'.cos.\' + config.Region + \'.myqcloud.com/\' + newKey; // 返回上传的绝对URL

        // sdk提供的COS上传函数,如果想批量上传,在这里加FOR循环即可。
        cos.postObject({
          Bucket: config.Bucket,  // 存储桶
          Region: config.Region,  // 地域
          Key: newKey,
          FilePath: filePath,     // 本地文件临时地址
          // onProgress: function (info) {   // 上传时基本信息
          //   console.log(JSON.stringify(info));
          // }
        },requestCallback(null,tempObj));
      }
    })
  },
});

// 上传图片回调函数
var requestCallback = function (err, data) {
  console.log(err || data);
  if (err && err.error) {
    wx.showModal({ title: \'返回错误\', content: \'请求失败:\' + err.error.Message + \';状态码:\' + err.statusCode, showCancel: false });
  } else if (err) {
    wx.showModal({ title: \'请求出错\', content: \'请求出错:\' + err + \';状态码:\' + err.statusCode, showCancel: false });
  } else {
    console.log(data);
    wx.showToast({ title: \'请求成功\', icon: \'success\', duration: 3000 });
  }
};


 

个人避坑解决方案

原因:开始上传图片到cos的项目我是用TP3.2做的,但是上传到linux且高版本的php服务器上,发现我那个生成签名的php竟然报500错误,而我本地是windows且php版本低于5.5一切都很正常。至于是什么原因,我也没时间去解决,只能把生成签名的php文件改成tp5.0的放在另一个项目中,而我就以跨域的方式去请求签名。

1.php文件修改

// 增加跨域响应头
header(\'Content-Type: application/json\');
header(\'Allow-Control-Allow-Origin: *\');       // 这里修改允许跨域访问的网站
header(\'Allow-Control-Allow-Headers: origin,accept,content-type\');

// 增加前端jsonp参数
$callback = input(\'callback\') ? input(\'callback\') : \'\';

// 以回调函数返回签名到前端
echo $callback . \'(\' . json_encode($data) . \')\';

 

2.js部分修改(主要改成跨域请求签名)

// 计算签名
var getAuthorization = function (options, callback) {
    var baseUrl = $("#cosurl").attr("urls");
    var url = baseUrl;

    $.ajax({    
        url:url,    
        dataType: \'jsonp\',  //类型
        jsonp: "callback",  // 参数    后台接受的是回掉函数名 
        //data:"",  
        type:\'get\',
        success: function(result) {
            callback(null, {
                Authorization: result.Authorization,    // 跨域拿到签名
                XCosSecurityToken: result.XCosSecurityToken,
            });

        },  
        error:function(result) {  
            callback(\'获取签名出错\');
        }
    })
};

 

个人微信公众号

以上是关于微信小程序/网站 上传图片到腾讯云COS的主要内容,如果未能解决你的问题,请参考以下文章

5行代码实现微信小程序图片上传与腾讯免费5G存储空间的使用

一个小时快速搭建微信小程序

微信小程序--图片相关问题合辑

微信小程序基于腾讯云对象存储的图片上传

如何在typecho中使用腾讯云对象存储cos?

小程序开发:上传图片到腾讯云