使用SAS WEBAPI的精细上传器azure blob

时间:2014-04-18 00:58:39

标签: jquery azure fine-uploader

在这里输入图像描述我正在开发一个纯html / javascript项目,它将一个文件以块的形式上传到Azure Blob存储。

我有一个HTML5 / jquery解决方案,适用于大型视频文件。它将创建并使用SAS令牌,使用MVC 4和WEBAPI将大文件上载到Azure存储中。 我不能使用此解决方案,因为HTML5使用一种名为split()的方法,在Safari或iOS便携式电话中不支持。所以我开始关注FineUploader解决方案。

我能够让签名端点与WEBAPI一起工作,返回一个看起来像这样的SAS ...... ' https://sike42.blob.core.windows.net/videos/CAM00281.mp4?sv=2013-08-15&sr=b&sig=PMwXaWLreN2uyHANtEBH1%2BwGB5%2FPjJ2h%2F5ML3pHev%2FM%3D&se=2014-04-18T01%3A12%3A33Z&sp=rwl

我打开了Debug并且能够在从它返回之后立即看到它 签名:{endpoint:' / api / signature'

我收到错误

NetworkError:404 Not Found - http://one27.0.0.1:1369/%3Cstring%20xmlns=%22http://schemas.microsoft.com/2003/10/Serialization/%22%3Ehttps://sike42.blob.core.windows.net/videos/CAM00281.mp4?sv=2013-08-15&sr=b&sig=PMwXaWLreN2uyHANtEBH1%2BwGB5%2FPjJ2h%2F5ML3pHev%2FM%3D&se=2014-04-18T01%3A12%3A33Z&sp=rwl%3C/string%3E"

我对如何解决这个问题感到有些困惑,并认为我会在谷歌搜索后寻求一些帮助并寻找答案的支持。

看起来有些XML正在SAS和URL之间进行,或者发生了一些奇怪的事情。

$(document).ready(function () {
    $("#fine-uploader").fineUploaderAzure({

        debug : true,
        request: {
            endpoint : 'https://sike42.blob.core.windows.net/videos/'

        },
        signature: {
            endpoint: '/api/signature'
        },
        uploadSuccess: {
            endpoint: '/success'
        }


    });

非常感谢任何帮助

我无法发布我在firebug中看到的错误,因为这个嵌入式html编辑器不会在帖子中允许onetwentyseven.zero.zero。非常沮丧。

所以我发布了一个有效的链接(它使用Azure SAS以块的形式上传文件)

roku.azurewebsites.net

和一个链接,您可以使用fineuploader.js自己查看firebug中的错误

roku.azurewebsites.net/default.html

我为这个js代码支付了78美元,因为我认为我可以在不使用jquery slice()的情况下使用它在iPhone上进行分块(注意:iphone上不支持jquery slice)....请帮助一些支持

谢谢

    const string STORAGE_ACCOUNT_NAME = "sikeXXXXXX";

    const string STORAGE_ACCOUNT_KEY = "LccVXXXXXXXXXXXXXXXXXXXXXX==";
    static List<String> ALLOWED_CORS_ORIGINS = new List<String> { "roku.azurewebsites.net" };
    static List<String> ALLOWED_CORS_HEADERS = new List<String> { "x-ms-meta-qqfilename", "Content-Type", "x-ms-blob-type", "x-ms-blob-content-type" };

    //     x-ms-meta-qqfilename,                   x-ms-blob-type,   x-ms-blob-content-type,Content-Type


    const CorsHttpMethods ALLOWED_CORS_METHODS = CorsHttpMethods.Delete | CorsHttpMethods.Put | CorsHttpMethods.Post | CorsHttpMethods.Get;
    const int ALLOWED_CORS_AGE_DAYS = 5;
    const string SIGNATURE_SERVER_ENDPOINT_ADDRESS = "http://*:8080/signature/";
    const string UPLOAD_SUCCESS_ENDPOINT_ADDRESS = "http://*:8080/success/";
方法startServer();

中的

如果它进入无限循环,我如何在apicontroller中运行它?

我应该将此代码放在辅助角色中吗?

headers =

缓存控制私有 内容长度3529 Content-Type text / html;字符集= utf-8的 日期星期二,2014年5月13日02:37:54 GMT 服务器Microsoft-IIS / 8.0 X-AspNet-Version 4.0.30319 X-Powered-By ASP.NET X-SourceFiles =?UTF-8 2 B 4 QzpcMjAxM1xTaWtlNDJcU2lrZTQyLldlYlw8c3RyaW5nIHhtbG5zPSJodHRwOlxzY2hlbWFzLm1pY3Jvc29mdC5jb21cMjAwM1wxMFxTZXJpYWxpemF0aW9uXCI + aHR0cHM6XHNpa2U0Mi5ibG9iLmNvcmUud2luZG93cy5uZXRcdmlkZW9zXEFueXRoaW5nNTEzMjAxNCAyMzc0NCBBTQ ==?= 请求标题 接受text / html,application / xhtml + xml,application / xml; q = 0.9, / ; q = 0.8 Accept-Encoding gzip,deflate Accept-Language en-US,en; q = 0.5 内容长度2462553 内容类型视频/ mp4 Cookie __RequestVerificationToken = 0j8Re7pnVCpuw4sU59jYAioM9ESekxdTt6pudAdNPQyJTRjxyN65tMhZkAg1wDE_C464UDLGv3kTN2djj87SNwz8oc_UZNnVCXEYoL7y9Po1 主机
Referer /default.html User-Agent Mozilla / 5.0(Windows NT 6.3; WOW64; rv:29.0)Gecko / 20100101 Firefox / 29.0 x-ms-blob-type BlockBlob x-ms-meta-qqfilename CAM00281.mp4

html =从客户端(&lt;)中检测到潜在危险的Request.Path值。

P.S。我会把错误的SS包括在内......但是我需要10个代表并且尚未获得它们。 ;-(

2 个答案:

答案 0 :(得分:1)

我正在努力解决与你一样的问题:

  • 我的WebAPI方法将有效的SAS网址返回给FineUploader;
  • FineUploader会尝试将文件上传到我的本地服务器而不是SAS URL。
  • 奇怪的是,SAS URL显示在FineUpload最终使用的URL中的某个位置。

问题原来是WebAPI自动将SAS URL序列化为JSON。这导致SAS URL格式错误 - 添加了一些额外的字符 - 而且FineUploader对这种共鸣感到困惑。在您的情况下,基于存在的 schemas.microsoft.com 文本,看起来SAS URL被序列化为XML。

凭借这种理解,我绕过了WebAPI的自动序列化。以下是我的GET /api/sas方法的有效实现。注意:GetSasForBlob直接来自Sample Azure Server

public HttpResponseMessage Get(string bloburi, string _method)
{
   var accountAndKey = new StorageCredentials(STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY);
   var sas = GetSasForBlob(accountAndKey, bloburi, _method);

   var content = new StringContent(sas);
   return new HttpResponseMessage {Content = content};
}

答案 1 :(得分:0)

正如我在John的回答中提到的那样,我的解决方案存在一些问题。首先我认为我对跨源请求有疑问,因为Chrome Dev Tools显示此消息错误:

XMLHttpRequest cannot load statuscode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers:{ Content-Type: text/plain; charset=utf-8}. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

不幸的是问题不在于CORS的设置。我设置CORSFineUploader's example完全相同,我知道问题必须在其他地方。

最后我发现了问题,我愿意与你分享我的解决方案,所以如果将来有人遇到同样的问题,他或她可以在比我解决它的时间更短的时间内解决问题。问题是John的片段返回了如下错误的响应消息:

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers: { Content-Type: text/plain; charset=utf-8 }

由于FineUploader正在等待包含SAS URI的字符串,因此无效。我不明白为什么在错误信息中我得到了我得到的但是没关系。有一个简单的解决方案,而不是返回由HttpResponseMessage创建的内容的StringContent我只是返回Content

    public ActionResult Signature(string bloburi, string _method)
    {
        // here provide your credentials
        var accountAndKey = new StorageCredentials(StorageAccountName, StorageAccountKey);
        // GetSasForBlob was provided in FineUploader's example
        var sas = GetSasForBlob(accountAndKey, bloburi, _method);

        var storageAccount = new CloudStorageAccount(accountAndKey, true);
        // ConfigureCors was also provided in FineUploader's example
        ConfigureCors(storageAccount);

        return Content(sas);
    }

我还略微编辑了ConfigureCors方法,因此不需要额外的方法来将设置输出到控制台(因为这在MVC 5项目中使用)。

    private static void ConfigureCors(CloudStorageAccount storageAccount)
    {
        var blobClient = storageAccount.CreateCloudBlobClient();
        var newProperties = blobClient.GetServiceProperties();

        newProperties.DefaultServiceVersion = "2013-08-15";
        blobClient.SetServiceProperties(newProperties);

        var ruleWideOpenWriter = new CorsRule()
        {
            AllowedHeaders = AllowedCorsHeaders,
            AllowedOrigins = AllowedCorsOrigins,
            AllowedMethods = AllowedCorsMethods,
            MaxAgeInSeconds = AllowedCorsAge
        };

        newProperties.Cors.CorsRules.Clear();
        newProperties.Cors.CorsRules.Add(ruleWideOpenWriter);
        blobClient.SetServiceProperties(newProperties);
    }