cos demo - zhouted/zhouted.github.io GitHub Wiki
COS是腾讯云提供的一种高扩展、低成本、可靠和安全存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。
上传页面需引入cos-js-sdk(下载:XML JavaScript SDK)
<script src="tencent/cos-js-sdk-v5.min.js"></script>
使用html原生input file标签
<input type="file" id="file" name="file" multiple="multiple" @change="onSelectFile">
或外包一层label
<label>
<input type="file" id="file" name="file" hidden multiple="multiple" @change="onSelectFile">
<span>选择上传文件...</span>
</label>
上传处理用到的js(示例使用了vue)
new Vue({
el: '#root',
data: {
cos: null,
bucket: 'test-1301758919',
region: 'ap-guangzhou',
prefix: 'test/',//文件存放路径前缀
uploading: false,
uploads: [],//正在上传的对象
},
created: function () {
this.init();
},
methods: {
init: function () {
var vue = this;
vue.cos = $.newCos(vue.prefix);
},
onSelectFile: function ($event) {
var vue = this;
var files = $event.target.files;
if (!files || !files.length) {
return;
}
var ups = []; //upload promises
vue.uploading = true;
for (var i = 0; i < files.length; i++) { //循环上传所选文件
var file = files[i];
var upload = {
cos: vue.cos,
bucket: vue.bucket,
region: vue.region,
key: vue.prefix + file.name,
file: file,
uploading: true, //正在上传
progress: { //存放进度
uploaded: 0,
percent: 0
},
}
upload.onFinish = function (err, data) {
vue.load();
vue.uploads.splice(vue.uploads.indexOf(this), 1);
}
upload.onProgress = function (progress) {
this.progress = progress;
vue.uploads[vue.uploads.indexOf(this)] = this;
};
ups.push($.uploadFile(upload));
vue.uploads.push(upload);
}
$.when.apply($, ups).then(function () {
$event.target.value = '';
vue.uploading = false;
});
},
toggleTask: function (upload) { //暂停/继续上传任务
if (upload.uploading) {
upload.cos.pauseTask(upload.taskId);
} else {
upload.cos.restartTask(upload.taskId);
}
upload.uploading = !upload.uploading;
},
},
}
公共方法可以注入到jquery
//cos: new cos instance
$.newCOS = function(prefix){
return new COS({
FileParallelLimit: 10,
getAuthorization: function(options, callback) {
console.log(options);
$.getJSON('/cos/sts', {prefix: prefix}, function(sts) {//后台提供的接口/cos/sts
var credentials = sts && sts.credentials;
if (!sts || !credentials) return console.error('credentials invalid');
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
XCosSecurityToken: credentials.sessionToken,
StartTime: sts.startTime,
ExpiredTime: sts.expiredTime,
});
});
}
});
}
//cos: upload file to cos
$.uploadCOS = function(upload){
var deferred = $.Deferred();
var uploadParam = {
Bucket: upload.bucket||'test-1301758919',
Region: upload.region||'ap-guangzhou',
Key: upload.key||upload.file.name,
Body: upload.file,
onTaskReady: function(taskId) {
upload.taskId = taskId;
},
onProgress: function (progressData) {
upload.onProgress && upload.onProgress(progressData);
},
}
upload.cos.sliceUploadFile(uploadParam, function(err, data) {
//err && console.error(err);
upload.onFinish && upload.onFinish(err, data);
deferred.resolve(err, data);
});
return deferred.promise();
}
用一个table显示上传进度
<table class="table table-striped table-hover" v-show="uploads.length">
<thead>
<tr>
<th>#</th><th>文件</th><th class="text-center">进度</th><th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(upload, idx) in uploads">
<td>{{idx+1}}</td>
<td>{{upload.file.name}}</td>
<td class="text-center">
<div class="progress" style="height:1.5rem;">
<div class="progress-bar" role="progressbar" :style="{width: upload.progress.percent*100+'%'}" aria-valuemin="0" aria-valuemax="100">
{{(upload.progress.percent*100).toFixed(0)}}%({{upload.progress.loaded}}/{{upload.file.size}})
</div>
</div>
</td>
<td class="text-center">
<button class="btn btn-link" @click="toggleTask(upload)">{{upload.uploading?'暂停':'继续'}}</button>
</td>
</tr>
</tbody>
</table>
pom.xml dependencies
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.19</version>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>cos-sts-java</artifactId>
<version>3.0.6</version>
</dependency>
CosController.java
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.cloudbutterfly.demo.service.CosService;
@RestController
@RequestMapping("/cos")
public class CosController {
@Autowired
CosService cosService;
@RequestMapping("/sts") //获取cos临时密钥sts接口
String getSTS(String prefix) {
JSONObject sts = cosService.getCredential(prefix);
return sts.toString();
}
@RequestMapping("/dl") //下载接口
void download(String key, HttpServletResponse response) throws IOException {
String url = cosService.getCdnUrl(key);
response.sendRedirect(url);
}
}
CosService.java
import java.time.Instant;
import java.util.TreeMap;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import com.tencent.cloud.CosStsClient;
@Service
public class CosService {
@Autowired CosConfig config;
public JSONObject getCredential(String prefix) {
TreeMap<String, Object> map = new TreeMap<String, Object>();
try {
map.put("SecretId", config.getSecretId());
map.put("SecretKey", config.getSecretKey());
map.put("durationSeconds", 1800);
map.put("bucket", config.getBucket());
map.put("region", config.getRegion());
map.put("allowPrefix", prefix == null ? "*" : prefix + "*");
String[] allowActions = new String[] {
"name/cos:InitiateMultipartUpload", "name/cos:ListMultipartUploads", "name/cos:ListParts", "name/cos:UploadPart", "name/cos:CompleteMultipartUpload",// 分片上传
};
map.put("allowActions", allowActions);
JSONObject credential = CosStsClient.getCredential(map);
return credential;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//获取带鉴权的cdn访问url。如果不使用cdn则需调用cos.generatePresignedUrl(req)生成带签名的url
public String getCdnUrl(String key) {
long ts = Instant.now().getEpochSecond();
String sign = DigestUtils.md5DigestAsHex(String.format("%s/%s%d", config.getCdnKey(), key, ts).getBytes());
return String.format("%s%s?sign=%s&t=%d", config.getCdnAp(), key, sign, ts);
}
}
CosConfig是配置类
public class CosConfig {
private String bucket;//存储桶名
private String region;//存储区域
private String secretId;//访问密钥id
private String secretKey;//访问密钥key
private String cdnAp;//CDN接入点
private String cdnKey;//CDN鉴权key
}