php搭配vue使用云上传解决大文件上传问题

本场景使用php进行开发,在日常业务中上传功能很常见,小图片、小文件上传我们服务宽带影响不大,但是遇到大文件10MB以上的即使分片上传还是会容易丢失或者拉爆服务器宽带。
所以现在大部分场景文件上传都是用云上传,本次介绍的是腾讯云cos前端直传功能。

1.首页我们需要部署后端,我的示例使用php做为后端

首页安装cos依赖包 cos参考文档 [腾讯云文档](https://cloud.tencent.com/document/product/436)
composer require qcloud/cos-sdk-v5
//定义一个私有方法用于初始化
private function _client(): Client
{
$secretId = $this->config['腾讯云cosappid'];
$secretKey = $this->config['腾讯云cossecretKey'];
$region = $this->config['存储同地区'];
return new Client(
array(
'region' => $region,
'schema' => 'https', //协议头部,默认为http
'credentials' => array(
'secretId' => $secretId,
'secretKey' => $secretKey)
));
}
//获取cos临时上传签名(请匆使用原始ID和key因为此内容需要返回前端进行上传使用)
public function getTemporaryKey()
{
$sts = new Sts();
$config = [
'url' => 'https://sts.tencentcloudapi.com', // url和domain保持一致
'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
'proxy' => '',
'secretId' => $this->config['secretId'], // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
'secretKey' => $this->config['secretKey'], // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
'bucket' => $this->config['bucketAgency'], // 换成你的 bucket
'region' => $this->config['regionAgency'], // 换成 bucket 所在园区
'durationSeconds' => 120, // 密钥有效期
'allowPrefix' => [$this->config['dirnameAgency'] . '/'], // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/ 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
// 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
'allowActions' => [
// 简单上传
'name/cos:PutObject',
'name/cos:PostObject',
// 分片上传
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload'
],
];
try {
$tempKeys = $sts->getTempKeys($config);
} catch (\Throwable $exception) {
return ['status' => 1, 'msg' => $exception->getMessage()];
}
//返回临时密钥
return ['status' => 0, 'data' => $tempKeys];
}

2.上面php后端已经获取临时密钥
需要用到腾讯官方js依赖前端依赖

//引入sdk
import COS from 'cos-js-sdk-v5';
const cos = new COS({
// getAuthorization 必选参数
getAuthorization: function (options, callback) {
// 初始化时不会调用,只有调用 cos 方法(例如 cos.putObject)时才会进入
// 异步获取临时密钥
// 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
// 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
// STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048

    const url = 'http://example.com/server/sts.php'; // url 替换成您自己的后端服务
    const xhr = new XMLHttpRequest();
    let data = null;
    let credentials = null;
    xhr.open('GET', url, true);
    xhr.onload = function (e) {
        try {
          data = JSON.parse(e.target.responseText);
          credentials = data.credentials;
        } catch (e) {
        }
        if (!data || !credentials) {
          return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2))
        };
        callback({
          TmpSecretId: credentials.tmpSecretId,
          TmpSecretKey: credentials.tmpSecretKey,
          SecurityToken: credentials.sessionToken,
          // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
          StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
          ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
      });
    };
    xhr.send();
}
});

//如果不用sdk自带的请求也可以在外部 使用Promise 参考下面示例

uplFile(file) {
return new Promise((resolve, reject) => {
let cosConfig = {}
let fileType = file.name.split('.')
let fileEndType = fileType[fileType.length - 1]
if (!['ppt', 'pptx', 'docx', 'doc', 'pdf', 'pptm', 'ppsx', 'ppsm', 'pps',
'potx', 'pot', 'potm', 'dpt', 'dps', 'dot', 'dotx', 'docm', 'dotm', 'wps', 'wpt',
'et', 'ett', 'xlt', 'xltm', 'csv', 'xls', 'xlsx', 'xlsm','jpg','png','base64','webp','jpeg','pdf'
].includes(fileEndType)) {
reject({
'msg': '不支持上传' + fileEndType + '类型!'
})
return false
}
//此方法为自行的请求临时签名接口
getUplTemporaryConfig({
size: file.size
}).then(res => {
if (res.code != 200) {
reject({
'msg': res.message,
'status':-2
})
return false
}
cosConfig = res.data
console.log('cosConfig')
console.log(cosConfig)
var cos = new COS({
getAuthorization: function(options, callback) {

					callback({
						TmpSecretId: cosConfig.cos_config.credentials
							.tmpSecretId,
						TmpSecretKey: cosConfig.cos_config.credentials
							.tmpSecretKey,
						SecurityToken: cosConfig.cos_config.credentials
							.sessionToken,
						// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
						StartTime: cosConfig.cos_config
							.startTime, // 时间戳,单位秒,如:1580000000
						ExpiredTime: cosConfig.cos_config
							.expiredTime, // 时间戳,单位秒,如:1580000000
					});
				}

			});
			let fileName = cosConfig.cos_dirname_copy + cosConfig.file_name + '.' + fileEndType
			cos.uploadFile({
				Bucket: cosConfig.cos_bucket_copy,
				/* 填入您自己的存储桶,必须字段 */
				Region: cosConfig.cos_region_copy,
				/* 存储桶所在地域,例如ap-beijing,必须字段 */
				Key: fileName,
				/* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */
				Body: file,
				/* 必须,上传文件对象,可以是input[type="file"]标签选择本地文件后得到的file对象 */
				SliceSize: 1024 * 1024 * 5,
				/* 触发分块上传的阈值,超过5MB使用分块上传,非必须 */
				onTaskReady: function(taskId) {
					/* 非必须 */
					console.log(taskId);
				},
				onProgress: function(progressData) {
					/* 非必须 */
					console.log('JSON.stringify(progressData)');
					console.log(progressData);
				},
				onFileFinish: function(err, data, options) {
					/* 非必须 */
					console.log(options.Key + '上传' + (err ? '失败' : '完成'));
					if (err) {
						reject({
							'msg': '上传失败'
						})
					}
				},
				// // 支持自定义headers 非必须
				// Headers: {
				// 	'Access-Control-Allow-Origin': '*'
				// },
			}, function(err, data) {
				console.log('上传操作成功')
				console.log(data)
				if (data.statusCode == 200) {
					console.log('进入成功')
					console.log('进入resolve')
					resolve({
						'msg': '上传成功',
						'data': {
							'origin_name': file.name,
							'size': file.size,
							'url': cosConfig.cos_domain_copy + '/' + fileName,
							'save_path': fileName,
							'mime_type': fileEndType,
							'extension': fileEndType
						}
					})
				} else {
					console.log('进入失败')
					reject({
						'msg': '上传失败',
						'status':-1
					})
				}
			});
		})
	});
}

自此完成了前端直传云端功能,这样即可解决大文件拉爆服务器的尴尬,也可以提升上传速度,本人使用10M宽带的服务器上传60MB文件需要大致50秒左右,使用cos直传仅需3-5秒。此案例参考文件码二维码生成器,获得灵感进行实现的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值