前面2篇,我们介绍了七牛云的客户端文件直传,客户端直传存在一个问题,就是上传凭证token在前端是暴露的,因此考虑采取通过业务服务器(自己家的服务器)代为上传文件。
整个上传流程用户在前端选择要上传的文件,通过ajax调用业务服务器的上传接口
业务服务器将用户选择的文件,上传到七牛云服务器
七牛云反馈给业务服务器数据
业务服务器反馈给前端数据
我们知道,当用户通过post将form提交到业务服务器时,文件会被放置到服务器上的一个临时位置,此时就相当于客户将文件了一次,然后业务服务器再将该文件上传到七牛云,此时相当于又上传了一次,因此,通过后台上传实际上传了2次,时间肯定会大大加长。
前端html核心代码:
只有一个表单了,不需要token
上传
前端ajax核心代码:
var domain="http://yourdomain.clouddn.com/";
$("#submit").on('click',function(){
var formdata=new FormData();
formdata.append('file',$("#file")[0].files[0]);
$.ajax({
type:'post',
url:'/api/qiniu/up',
data:formdata,
cache: false,
contentType:false,
processData: false,
dataType:"json",
error: function(request) {
alert(request.status);
},
success: function(data) {
$("#preview img").attr("src",domain+data.key);
}
});
});
后台php(YII框架)核心代码:
通过七牛云提供的php SDK,很简单的完成了上传$accessKey =qn_accesskey;
$secretKey = qn_secretkey;
$auth = new Auth($accessKey, $secretKey);
$bucket =qn_bucket;
$token= $auth->uploadToken($bucket);
$files=$_FILES['file'];
$filePath = $files['tmp_name'];
// 上传到七牛后保存的文件名
$key =md5(uniqid(md5(microtime(true)),true)).'.'.pathinfo($files['name'])['extension'];
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传。
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
if ($err !== null) {
$return['code']=0;
$return['message']="上传失败";
} else {
$return['code']=1;
$return['message']="上传成功";
$return['key']=$ret['key'];
}
return $this->success($return);
我们前面猜想了,通过后台服务器上传,上传时间会加长,因此我也做了一个测试,记录用户点击时间date1,ajax上传成功时记录date2,然后找了一张1.9M的图片做上传测试,结果如下
客户端直传通过服务器代传
第一次376ms13716ms
第二次379ms14051ms
我的服务器带宽比较小,因此效果对比就非常的明显了,
七牛文件上传优点缺点应用场景
客户端直传速度快暴露了token,可能会被人利用,有安全风险如果产品供内部人员使用,如管理后台,且上传一些大文件,如视频管理,我会选用此方案
业务服务器代传不会暴露token,比较安全速度慢如果产品给用户使用,上传的是图片一类小文件,可以选择此类方式