运用七牛云存储的一些经验总结

近段时刻将运用七牛云存储来寄存用户上传的数据,客户端经由历程七牛的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简化代码了…

    原文作者:P_Chou水冗
    原文地址: https://segmentfault.com/a/1190000000592048
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞