近段时刻将运用七牛云存储来寄存用户上传的数据,客户端经由历程七牛的js-sdk与七牛交互,服务端C#完成了七牛相干的接口。在这历程当中多多少少遇到点题目,在这里总结一下。原文:运用七牛云存储的一些经验总结
599毛病处置惩罚
假如在与七牛的交互中涌现http状况码为599的毛病,一句话,不要犹疑,直接联络七牛技术支撑。七牛的文档也在许多处所提到这个毛病,都是指点人人去联络技术支撑的。笔者是在分块上传后的mkfile
挪用时涌现的,联络技术支撑后,说是调整了一下,让我重试。厥后就好了…
分块上传没法从回调中取得文件的原始名
简朴上传采纳的是multipart/form-data体式格局上传,七牛服务端能够从要求中取得文件的原始名,并支撑运用魔法变量$(fname)
回调营业服务器。不过当运用分片上传的时刻状况有所差别。分片上传须要在末了挪用mkfile
,来将分片拼接起来。然则,mkfile
接口支撑一般的要求,并没有附带文件名,所以七牛也就没法取得文件名,此时从$(fname)
中是取不到文件名的。这个题目我也向七牛技术支撑提交了题目,获得的效果是运用自定义变量mkfile
支撑将自定义变量放在url中,回调的时刻自定义变量能够传递给营业服务器。
慎用图片预处置惩罚
七牛云支撑许多对文件的预处置惩罚,个中最经常使用的应当就是图片预处置惩罚了,能够对图片的大小做变更等。七牛引荐运用GET的体式格局直接指定图片处置惩罚效果的url,像如许:
http://qiniuphotos.qiniudn.com/gogopher.jpg?imageView2/1/w/200/h/200
处置惩罚后的图片会自动缓存,用户不必体贴,只需每次接见都用这个url就好了。但是,笔者在最先的时刻,为了坚持与其他文件情势一致的处置惩罚要领,对图片运用了预处置惩罚(因为视频什么的只能预处置惩罚),即在token中指定了预处置惩罚。此时题目涌现了,从背景的日记看到,图片的预处置惩罚关照回调居然比一般的上传胜利回调还要快!这就致使预处置惩罚效果到来之前,我的营业服务器的数据库中还没有这个图片,没法保留预处置惩罚效果了。所以引荐照样运用url直接处置惩罚,对图片要慎用预处置惩罚
视频文件没法快进播放
通经常使用户在寓目视频的时刻都邑依据自身的喜欢,快速将视频定位到指定的时刻播放。完成这个功用,须要视频自身有症结帧信息、服务端须要支撑症结帧播放要求,在这篇文章中有细致议论。
然则笔者发明,在运用七牛云转化后的视频,如许做是无效的。因而征询技术支撑,获得的答案是:转化的文件是具有症结帧的,但七牛运用CDN加快,所以症结帧要求须要CDN的支撑,假如想要用这个功用的话,须要零丁联络贩卖或技术支撑在CDN上设置,而且时刻比较长。笔者联络了贩卖和技术支撑,说是帮我设置,但到如今还没有搞定,因为近来这个也不是迥殊主要,所以也没有跟下去。
Callback校验
这是可选的一个步骤。因为七牛云会在上传完成以后回调营业服务器,所以理论上说营业服务器须要校验这个回调的合理性。道理在七牛的文档中有,须要用到HMAC-SHA1
署名函数。然则七牛的sdk中没有供应直接的体式格局来做校验,在研读文档、屡次失利和检察sdk源码后,笔者终究校验胜利了。症结的不合在于,文档中的这句话:
猎取明文:data = Request.URL.Path +”\n” +Request.Body
这里的Request.URL.Path
是不是包括Querystring?答案是包括的!下面是笔者C#服务端的校验代码,运用的是ASP.NET Web Api:
byte[] key = System.Text.Encoding.UTF8.GetBytes(Qiniu.Conf.Config.SECRET_KEY);
using (HMACSHA1 hmac = new HMACSHA1(key))
{
var t = filterContext.Request.Content.ReadAsStringAsync();
t.Wait();
string rawbody = t.Result;
log.DebugFormat("request's rawbody : {0}", rawbody);
string text = filterContext.Request.RequestUri.PathAndQuery + "\n" + rawbody;
log.DebugFormat("PathAndQuery + \\n + rawbody : {0}", text);
byte[] digest = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(text));
string computed = Qiniu.Util.Base64URLSafe.Encode(digest);
log.DebugFormat("Computed hash after base64 : {0}", computed);
IEnumerable<string> auths;
if (filterContext.Request.Headers.TryGetValues("Authorization", out auths) && auths.Count() == 1)
{
string auth = auths.First();
log.DebugFormat("Authorization in header : {0}", auth);
if (auth.StartsWith("QBox "))
{
var arr = auth.Substring(5).Split(':');
if (arr.Length == 2)
{
if (arr[1] != computed)
{
log.ErrorFormat("Authorization failed. Since auth from header {0} not equals computed {1}", arr[1], computed);
}
else
{
log.Debug("Authorization success.");
//only pass can be return
return;
}
}
else
{
log.Error("Callback Authorization's format is invalid, can not find two part after split by ':'.");
}
}
else
{
log.Error("Callback Authorization's format is invalid, missing leading 'QBox '.");
}
}
else
{
log.Error("The request from qiniu callback is missing 'Authorization'");
}
filterContext.Response = filterContext.Request.CreateResponse(System.Net.HttpStatusCode.Forbidden);
}
以下几个注重点:
- 明文应当是要求的path+querystring部份和rawbody
- 关于.NET而言,明文和key都须要用UTF-8编码变更成字节才举行署名。而php中的hash_hmac函数完整不必这么庞杂…
- 署名的效果再用base64的url平安的体式格局编码,再与要求的http头部的Authorization比较
发起官方在文档中到场一些相对底层一些的编程言语的完成,php太高端了…
js-sdk完成略显粗拙
在运用历程当中,我发明官方的js-sdk有几个我以为不好的处所:
不能为每一个文件猎取UpToken
试想,在文件上传历程当中有猎取UpToken是必需的,而且UpToken又须要包括预处置惩罚指令,差别的文件明显须要差别的UpToken,而在js-sdk的完成中,只在初始化这个上传组件对象的时刻要求一次上传凭据,背面一切的上传都须要运用这个预先获得的UpToken:
uploader.bind('Init', function(up, params) {
getUpToken();
});
因而我修改了这部份,在BeforeUpload
事宜中要求UpToken。发起官方斟酌变动这个处所
只能完成分片上传,没法断点续传
js-sdk的完成在分片上传的完成上,是很简朴的,不仅没有运用分片,而是分块(一块4m,挪用mkblk),而且没有完成耐久化ctx,或许相似的回调或接口。4m分块这个题目还能够不追查,没有完成耐久化ctx就说不过去了,不耐久化怎样完成断点续传撒?!就算不完成,也应当给出回调的进口,让挪用者来完成耐久化,而我着实没法找到这个’空子’可钻,只能直接在源码上改动了。
没有复用盛行类库的东西
这个实在算不上题目,因为作为一个不依靠jquery的sdk,固然不能运用jquery现成的东西,比方ajax。不依靠jquery就算了,依靠plupload是几个意义嘛,还依靠全局对象…因而末了,我痛快自身将sdk改成了Backbone的类,将不要的东西一切去掉,运用jquery和underscore简化代码了…