腾讯云 对象存储之COS上传文件,视频

这篇博客介绍了如何在腾讯云COS中使用PHP获取临时密钥,并通过JavaScript进行文件上传。首先展示了一个PHP控制器的代码,用于获取临时密钥并计算签名。然后提供了JavaScript代码,演示了如何使用获取的签名进行Ajax PUT方式的文件上传。文章以实际代码为主,适合需要实现类似功能的开发者参考。
部署运行你感兴趣的模型镜像

闲话不唠 直接上代码   

使用 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>

转载于:https://www.cnblogs.com/JdsyJ/p/9450590.html

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在使用SpringBoot整合腾讯云COS对象存储实现文件上传功能。根据提供的引用内容,我们需要进行以下步骤:1.开通腾讯云对象存储服务,并获取SecretId、SecretKey、存储桶名称(Bucket)、地域(Region)以及请求域名(URL)。2.在SpringBoot项目中引入腾讯云COS的JavaSDK依赖。3.配置腾讯云COS的相关参数(SecretId,SecretKey, Bucket名称,地域等)。4.编写文件上传的接口,使用COS客户端进行文件上传。具体步骤:第一步:开通腾讯云对象存储服务并获取密钥等信息-登录腾讯云控制台,进入对象存储COS服务,开通服务。-创建一个存储桶(Bucket),记录存储桶名称和所属地域。-在访问管理(CAM)中获取SecretId和SecretKey。第二步:在Spring Boot项目中添加依赖-在pom.xml中添加腾讯云COS JavaSDK依赖:```xml<dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.6.54</version></dependency>```第三步:配置application.yml(或application.properties)-根据引用[2]中的配置示例,在application.yml中配置腾讯云COS参数:```yamltencent:cos:secretId: your-secret-id#替换为你的SecretIdsecretKey:your-secret-key#替换为你的SecretKeybucketName:your-bucket-name#存储桶名称region: ap-shanghai#存储桶所在地域url:https://your-bucket-name.cos.ap-shanghai.myqcloud.com #请求域名,根据实际情况修改```第四步:创建配置类读取配置(可选,也可以直接在Service中注入)-可以创建一个配置类来读取这些配置,例如:```java@Configurationpublicclass CosConfig {@Value("${tencent.cos.secretId}")privateString secretId;@Value("${tencent.cos.secretKey}")privateString secretKey;@Value("${tencent.cos.bucketName}")privateString bucketName;@Value("${tencent.cos.region}")private Stringregion;@Value("${tencent.cos.url}")privateString url;//生成COSClient@BeanpublicCOSClient cosClient(){COSCredentialscred =new BasicCOSCredentials(secretId,secretKey);ClientConfig clientConfig =new ClientConfig(newRegion(region));returnnew COSClient(cred, clientConfig);}//也可以将其他配置作为Bean注入,方便使用public StringgetBucketName(){return bucketName;}publicString getUrl() {returnurl;}}```第五步:编写文件上传服务-创建一个Service类,用于文件上传操作。```java@Servicepublic classCosService{@Autowiredprivate COSClientcosClient;@Autowiredprivate CosConfig cosConfig;publicString uploadFile(MultipartFilefile,String fileName) {try{//获取存储桶名称String bucketName =cosConfig.getBucketName();//指定文件在存储桶中的路径(可以按需修改)String key= "/" +fileName;//例如直接放在根目录下//将文件转换为输入流InputStreaminputStream= file.getInputStream();//创建上传对象ObjectMetadataobjectMetadata =new ObjectMetadata();//设置输入流长度objectMetadata.setContentLength(file.getSize());//上传文件PutObjectRequest putObjectRequest= newPutObjectRequest(bucketName, key, inputStream,objectMetadata);cosClient.putObject(putObjectRequest);//返回文件的访问URL(需要拼接)returncosConfig.getUrl() +key;}catch (Exception e) {e.printStackTrace();returnnull;}}}```第六步:编写Controller接口-创建一个Controller,提供文件上传的接口。```java@RestController@RequestMapping("/file")public classFileController{@Autowiredprivate CosService cosService;@PostMapping("/upload")public BaseResponse<String> uploadFile(@RequestParam("file") MultipartFilefile){if (file.isEmpty()) {returnResultUtils.error(400,"文件为空");}//生成文件名(可以使用UUID避免重复)StringoriginalFilename= file.getOriginalFilename();StringfileName =UUID.randomUUID().toString()+ originalFilename.substring(originalFilename.lastIndexOf("."));//上传文件Stringurl =cosService.uploadFile(file, fileName);if (url !=null){return ResultUtils.success(url);}else {returnResultUtils.error(500,"文件上传失败");}}}```注意:这里使用了引用[3]中的BaseResponse和ResultUtils来统一返回格式。第七步:测试-启动项目,使用Postman或前端页面上传文件,查看返回的文件URL。安全建议:-敏感信息(SecretId和SecretKey)不要直接写在配置文件中,建议使用配置中心或环境变量。相关问题:1.如何设置文件上传COS的指定目录?-在`uploadFile`方法中,修改key的值,例如:`Stringkey ="images/"+ fileName;`,则文件上传到存储桶的images目录下。2.如何限制上传文件的类型和大小?-可以在Controller中添加校验,或者使用Spring Boot的配置限制文件大小(在application.yml中配置`spring.servlet.multipart.max-file-size`和`max-request-size`)。3.如何实现文件下载和删除?-参考腾讯云COS SDK文档,使用`COSClient`的`getObject`方法下载文件,使用`deleteObject`方法删除文件。4.如何避免文件名冲突?-使用UUID生成新的文件名,如示例所示。5.如何保证上传的安全性?-使用临时密钥(STS)进行临时授权,避免直接使用永久密钥。以上即为使用Spring Boot整合腾讯云COS对象存储实现文件上传的基本步骤。</think>### 使用腾讯云COS实现文件上传的步骤 #### 1. **准备工作** - 开通腾讯云COS服务并创建存储桶 - 获取以下关键信息: - `SecretId`:访问密钥ID - `SecretKey`:访问密钥 - `BucketName`:存储桶名称(如 `example-bucket-1250000000`) - `Region`:存储桶地域(如 `ap-shanghai`) - 在腾讯云控制台完成存储桶权限配置[^1] #### 2. **Spring Boot项目配置** ##### (1) 添加依赖 ```xml <!-- pom.xml --> <dependency> <groupId>com.qcloud</groupId> <artifactId>cos_api</artifactId> <version>5.6.89</version> </dependency> ``` ##### (2) 配置参数 ```yaml # application.yml tencent: cos: secretId: your-secret-id # 替换为实际值 secretKey: your-secret-key bucketName: your-bucket-name region: ap-shanghai ``` #### 3. **核心代码实现** ##### (1) COS工具类 ```java @Component public class CosClient { @Value("${tencent.cos.secretId}") private String secretId; @Value("${tencent.cos.secretKey}") private String secretKey; @Value("${tencent.cos.bucketName}") private String bucketName; @Value("${tencent.cos.region}") private String region; // 获取COS客户端实例 public COSClient getCosClient() { COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); Region region = new Region(this.region); ClientConfig config = new ClientConfig(region); return new COSClient(cred, config); } // 获取存储桶名称 public String getBucketName() { return bucketName; } } ``` ##### (2) 文件上传服务 ```java @Service public class FileUploadService { @Autowired private CosClient cosClient; public String uploadFile(MultipartFile file) { try { COSClient client = cosClient.getCosClient(); String fileName = generateFileName(file.getOriginalFilename()); // 创建上传请求 PutObjectRequest request = new PutObjectRequest( cosClient.getBucketName(), fileName, file.getInputStream(), new ObjectMetadata() ); // 执行上传 client.putObject(request); client.shutdown(); // 返回文件访问URL return "https://" + cosClient.getBucketName() + ".cos." + cosClient.getRegion() + ".myqcloud.com/" + fileName; } catch (Exception e) { throw new RuntimeException("上传失败: " + e.getMessage()); } } // 生成唯一文件名 private String generateFileName(String originalName) { return UUID.randomUUID() + originalName.substring(originalName.lastIndexOf(".")); } } ``` ##### (3) 控制器接口 ```java @RestController @RequestMapping("/api/file") public class FileController { @Autowired private FileUploadService uploadService; @PostMapping("/upload") public BaseResponse<String> upload(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResultUtils.error(400, "文件不能为空"); } try { String url = uploadService.uploadFile(file); return ResultUtils.success(url); } catch (Exception e) { return ResultUtils.error(500, e.getMessage()); } } } ``` #### 4. **测试上传** 使用Postman发送 **multipart/form-data** 请求: ``` POST /api/file/upload Body: file=[选择文件] ``` 成功响应示例: ```json { "code": 0, "data": "https://example-bucket-1250000000.cos.ap-shanghai.myqcloud.com/3c7d8f90-a2b3.jpg", "message": "ok" } ``` #### 5. **安全建议** 1. 前端直传:使用临时密钥STS方案,避免暴露永久密钥[^2] 2. 文件校验: - 在服务端验证文件类型(如通过`file.getContentType()`) - 限制文件大小(Spring Boot配置`spring.servlet.multipart.max-file-size`) 3. 权限控制:在COS控制台设置Bucket访问策略为**私有读写** ### 常见问题解决 - **权限错误403**:检查SecretId/SecretKey是否正确,存储桶权限是否开启写入 - **连接超时**:确认服务器网络可访问`cos.${region}.myqcloud.com` - **大文件上传**:使用分块上传接口(`TransferManager`类) > 完整示例代码参考腾讯云官方文档:[Java SDK 使用指南](https://cloud.tencent.com/document/product/436/10199)[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值