JdsyJ

闲话不唠 直接上代码   

使用 put方式的js_web上传方式  使用的基本是demo里的东西,在官方也有着地址 https://github.com/tencentyun/cos-js-sdk-v5/tree/master/demo  这里只要讲下配置

 

以下是php代码

<?php
namespace Home\Controller;
use Think\Controller;
//use com\unionpay\acp\sdk\AcpService;
class IndexController extends Controller
{
// 配置参数
public $config = array(
\'Url\' => \'https://sts.api.qcloud.com/v2/index.php\',
\'Domain\' => \'sts.api.qcloud.com\',
\'Proxy\' => \'\',
\'SecretId\' => \'AKIDV5Yw9GCwVs481jB7asywi2CB3mNrtIEy\', // 固定密钥
\'SecretKey\' => \'gCXgeSFxUpywwmQs8C4lGZgdPzObeVBf\', // 固定密钥
\'Bucket\' => \'dsy-1252917505\',
\'Region\' => \'ap-beijing\',
\'AllowPrefix\' => \'*\', // 这里改成允许的路径前缀,这里可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg
);

public function __initialize($config){

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

public function index()
{
$this->display();
}

public function getSign(){
// 获取前端过来的参数
$method = isset($_GET[\'method\']) ? $_GET[\'method\'] : \'get\';
$pathname = isset($_GET[\'pathname\']) ? $_GET[\'pathname\'] : \'/\';

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

if ($tempKeys && isset($tempKeys[\'credentials\'])) {
$data = array(
\'Authorization\' => $this->getAuthorization($tempKeys, $method, $pathname),
\'XCosSecurityToken\' => $tempKeys[\'credentials\'][\'sessionToken\'],
);
} else {
$data = array(\'error\'=> $tempKeys);
}

// 返回数据给前端
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($data);
}
// 获取临时密钥
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:*\', // 这样写可以包含下面所有权限

// // 列出所有允许的操作
// // 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));

// 有效时间小于 30 秒就重新获取临时密钥,否则使用缓存的临时密钥
if (isset($_SESSION[\'tempKeysCache\']) && isset($_SESSION[\'tempKeysCache\'][\'expiredTime\']) && isset($_SESSION[\'tempKeysCache\'][\'policyStr\']) &&
$_SESSION[\'tempKeysCache\'][\'expiredTime\'] - time() > 30 && $_SESSION[\'tempKeysCache\'][\'policyStr\'] === $policyStr) {
return $_SESSION[\'tempKeysCache\'];
}

$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);
$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);
if (isset($result[\'data\'])) $result = $result[\'data\'];
$_SESSION[\'tempKeysCache\'] = $result;
$_SESSION[\'tempKeysCache\'][\'policyStr\'] = $policyStr;

return $result;
}
// 计算临时密钥用的签名
public function getSignature($opt, $key, $method) {
// global $config;
$formatString = $method . $this->config[\'Domain\'] . \'/v2/index.php?\' . $this->json2str($opt);
$sign = hash_hmac(\'sha1\', $formatString, $key,true);
// $sign = base64_encode(hex2bin($sign));
$sign = base64_encode($sign);
return $sign;
}
// obj 转 query string
public function json2str($obj) {
ksort($obj);
$arr = array();
foreach ($obj as $key => $val) {
array_push($arr, $key . \'=\' . $val);
}
return join(\'&\', $arr);
}
// 工具方法
public function getObjectKeys($obj)
{
$list = array_keys($obj);
sort($list);
return $list;
}

public function obj2str($obj)
{
$list = array();
$keyList = $this->getObjectKeys($obj);
$len = count($keyList);
for ($i = 0; $i < $len; $i++) {
$key = $keyList[$i];
$val = isset($obj[$key]) ? $obj[$key] : \'\';
$key = strtolower($key);
$list[] = rawurlencode($key) . \'=\' . rawurlencode($val);
}
return implode(\'&\', $list);
}
// 计算 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);

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

// 要用到的 Authorization 参数列表
$qSignAlgorithm = \'sha1\';
$qAk = $SecretId;
$qSignTime = $now . \';\' . $expired;
$qKeyTime = $now . \';\' . $expired;
$qHeaderList = strtolower(implode(\';\', $this->getObjectKeys($headers)));
$qUrlParamList = strtolower(implode(\';\', $this->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, $this->obj2str($query), $this->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;
}

以下是 js代码

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax Put 上传</title>
<style>
h1, h2 {
font-weight: normal;
}
#msg {
margin-top: 10px;
}
</style>
</head>
<body>

<h1>Ajax Put 上传1</h1>

<input id="fileSelector" type="file">
<input id="submitBtn" type="submit">

<div id="msg"></div>

<script>
(function () {
// 请求用到的参数
var Bucket = \'dsy-1252917505\';
var Region = \'ap-beijing\';
var protocol = location.protocol === \'https:\' ? \'https:\' : \'http:\';
var prefix = protocol + \'//\' + Bucket + \'.cos.\' + Region + \'.myqcloud.com/\';
// 计算签名
var getAuthorization = function (options, callback) {
var method = (options.Method || \'get\').toLowerCase();
var key = options.Key || \'\';
var pathname = key.indexOf(\'/\') === 0 ? key : \'/\' + key;

// var url = \'http://127.0.0.1:3000/sts-auth\' +
var url = \'http://192.168.51.185:81/tp3.2/index.php/Home/Index/getSign\' +
\'?method=\' + method +
\'&pathname=\' + encodeURIComponent(pathname);
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 {
console.error(AuthData);
callback(\'获取签名出错\');
}
};
xhr.onerror = function (e) {
callback(\'获取签名出错\');
};
xhr.send();
};
// 上传文件
var uploadFile = function (file, callback) {
var point = file.name.lastIndexOf(".");
var type = file.name.substr(point);
var name = new Date().getTime()+parseInt(10*Math.random());
// var Key = \'dir/\' + file.name; // 这里指定上传目录和文件名
var Key = \'dir/\' + name+type; // 这里指定上传目录和文件名
getAuthorization({Method: \'PUT\', Key: Key}, function (err, info) {
if (err) {
alert(err);
return;
}
var auth = info.Authorization;
var XCosSecurityToken = info.XCosSecurityToken;
var url = prefix + Key;
var xhr = new XMLHttpRequest();
xhr.open(\'PUT\', url, true);
xhr.setRequestHeader(\'Authorization\', auth);
XCosSecurityToken && xhr.setRequestHeader(\'x-cos-security-token\', XCosSecurityToken);
xhr.onload = function () {
if (xhr.status === 200 || xhr.status === 206) {
var ETag = xhr.getResponseHeader(\'etag\');
callback(null, {url: url, ETag: ETag});
} else {
callback(\'文件 \' + Key + \' 上传失败,状态码:\' + xhr.status);
}
};
xhr.onerror = function () {
callback(\'文件 \' + Key + \' 上传失败,请检查是否没配置 CORS 跨域规则\');
};
xhr.send(file);
});
};
// 监听表单提交
document.getElementById(\'submitBtn\').onclick = function (e) {

var file = document.getElementById(\'fileSelector\').files[0];
if (!file) {
document.getElementById(\'msg\').innerText = \'未选择上传文件\';
return;
}
file && uploadFile(file, function (err, data) {
console.log(err || data);
document.getElementById(\'msg\').innerText = err ? err : (\'上传成功,ETag=\' + data.ETag);
});
};
})();
</script>

</body>
</html>

分类:

技术点:

相关文章: