zoukankan      html  css  js  c++  java
  • Javascript 上传文件到Azure存储

    对一些前端工程师来讲,使用javascript上传文件到Azure存储中可能是需要掌握的技能,希望这篇博客能给到帮助。

    在开始前我们需要了解以下几点:

    共享访问签名(Shared Access Signature(SAS)

    Azure 存储服务的跨域资源共享 (CORS) 支持

    共享访问签名

    共享访问签名,是用于提供对Windows Azure Storage中的Container,Blob,Table以及Queue在特定时间范围内进行有限权限访问的URL。通常情况下,我们访问Azure存储都是以账户名和密码的方式来实现的,通过这种方式也给使用者包括增删改在内的最大的访问权限,但是在实际情况中,我们可能希望用户只有读的权限,同时我们也不希望将账户名和密码泄露出去,共享访问签名很好的解决了这类问题。我们在使用Javascript上传时就是通过共享访问签名的URL来进行的。

    Azure 存储服务的跨域资源共享 (CORS) 支持

    大概在2014年3月份的时候Azure已经支持CORS,经过测试目前中国版和国际版都已经支持,我们在使用Javascript上传的时候是将资源以PUT的方式上传到类似于http://***.blob.core.chinacloudapi.cn这样域名的地方,这就涉及到CORS的问题,在默认情况下Azure存储是禁用CORS的,所以我们需要使用版本 2013-08-15 或更高版本设置适当的服务属性,并向服务属性中添加 CORS 规则,如果我们没有启用CORS规则,我们可能会得到403错误,使用Fiddler工具会得到更详细的错误信息:”CORS not enabled or no matching rule found for this request”。

    通过上面的描述,我们在开始编程前,我们需要SAS URL,还需要为我们的blob配置CORS规则,这些我们可以通过Azure SDK来实现,关于这部分我就不介绍了,详细请阅读:#SAS:http://www.windowsazure.cn/zh-cn/documentation/articles/storage-dotnet-shared-access-signature-part-2/

    #CORS:http://blogs.msdn.com/b/windowsazurestorage/archive/2014/02/03/windows-azure-storage-introducing-cors.aspx

    如果我们不太了解C#,我们可以借助Azure Storage Explorer来进行配置,下面我介绍下简单的配置:

    1)  得到SAS URL

                           

    打开Azure Storage Explorer点击“Security”,选择SAS失效的时间,并选择赋予相应的权限,如上图高亮标注的部分。

    2)  配置CORS规则

     

    打开Azure Storage Explorer鼠标停留在”Blob Containers”,这时会出现CORS设置按钮,点击新增CORS规则,并如上图设置,关于具体的设置信息,请阅读:https://msdn.microsoft.com/zh-cn/library/azure/dn535601.aspx?f=255&MSPPError=-2147217396,图中的设置是我测试的字段,可作为参考。

    下面是具体的代码

    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    
    <head>
    
        <title>File Uploader</title>
    
     
    
        <script src="Scripts/jquery-1.10.2.min.js"></script>
    
     
    
        <script>
    
            var maxBlockSize = 256 * 1024;//Each file will   be split in 256 KB.
    
            var numberOfBlocks = 1;
    
            var selectedFile = null;
    
            var currentFilePointer = 0;
    
            var totalBytesRemaining = 0;
    
            var blockIds = new Array();
    
            var blockIdPrefix = "block-";
    
            var submitUri = null;
    
            var bytesUploaded = 0;
    
     
    
            $(document).ready(function () {
    
                $("#output").hide();
    
                $("#file").bind('change',   handleFileSelect);
    
                if (window.File &&   window.FileReader && window.FileList && window.Blob) {
    
                    // Great success!   All the File APIs are supported.
    
                } else {
    
                    alert('The File APIs are   not fully supported in this browser.');
    
                }
    
            });
    
     
    
            //Read the file and find out how   many blocks we would need to split it.
    
            function handleFileSelect(e) {
    
                maxBlockSize = 256 *   1024;
    
                currentFilePointer =   0;
    
                totalBytesRemaining =   0;
    
                var files = e.target.files;
    
                selectedFile =   files[0];
    
                $("#output").show();
    
                $("#fileName").text(selectedFile.name);
    
                $("#fileSize").text(selectedFile.size);
    
                $("#fileType").text(selectedFile.type);
    
                var fileSize = selectedFile.size;
    
                if (fileSize < maxBlockSize) {
    
                    maxBlockSize =   fileSize;
    
                    console.log("max block   size = " +   maxBlockSize);
    
                }
    
                totalBytesRemaining =   fileSize;
    
                if (fileSize % maxBlockSize == 0) {
    
                    numberOfBlocks =   fileSize / maxBlockSize;
    
                } else {
    
                    numberOfBlocks =   parseInt(fileSize / maxBlockSize, 10) + 1;
    
                }
    
                console.log("total blocks   = " +   numberOfBlocks);
    
                var baseUrl = $("#sasUrl").val();
    
                var indexOfQueryStart = baseUrl.indexOf("?");
    
                submitUri =   baseUrl.substring(0, indexOfQueryStart) + '/' + selectedFile.name +   baseUrl.substring(indexOfQueryStart);
    
                  console.log(submitUri);
    
            }
    
     
    
            var reader = new FileReader();
    
     
    
            reader.onloadend = function (evt) {
    
                if (evt.target.readyState ==   FileReader.DONE) { // DONE == 2
    
                    var uri = submitUri + '&comp=block&blockid=' +   blockIds[blockIds.length - 1];
    
                    var requestData = new Uint8Array(evt.target.result);
    
                    $.ajax({
    
                        url: uri,
    
                        type: "PUT",
    
                        data:   requestData,
    
                        processData: false,
    
                        beforeSend: function (xhr) {
    
                            xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
    
                              xhr.setRequestHeader('Content-Length', requestData.length);
    
                        },
    
                        success: function (data, status) {
    
                              console.log(data);
    
                              console.log(status);
    
                              bytesUploaded += requestData.length;
    
                            var percentComplete =   ((parseFloat(bytesUploaded) / parseFloat(selectedFile.size)) *   100).toFixed(2);
    
                            $("#fileUploadProgress").text(percentComplete   + "   %");
    
                              uploadFileInBlocks();
    
                        },
    
                        error: function (xhr, desc, err)   {
    
                              console.log(desc);
    
                              console.log(err);
    
                        }
    
                    });
    
                }
    
            };
    
     
    
            function uploadFileInBlocks() {
    
                if (totalBytesRemaining > 0) {
    
                    console.log("current file   pointer = " + currentFilePointer + " bytes read = " + maxBlockSize);
    
                    var fileContent =   selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
    
                    var blockId = blockIdPrefix +   pad(blockIds.length, 6);
    
                    console.log("block id =   " +   blockId);
    
                      blockIds.push(btoa(blockId));
    
                      reader.readAsArrayBuffer(fileContent);
    
                    currentFilePointer   += maxBlockSize;
    
                      totalBytesRemaining -= maxBlockSize;
    
                    if (totalBytesRemaining <   maxBlockSize) {
    
                        maxBlockSize =   totalBytesRemaining;
    
                    }
    
                } else {
    
                    commitBlockList();
    
                }
    
            }
    
     
    
            function commitBlockList() {
    
                var uri = submitUri + '&comp=blocklist';
    
                console.log(uri);
    
                var requestBody = '<?xml   version="1.0" encoding="utf-8"?><BlockList>';
    
                for (var i = 0; i < blockIds.length;   i++) {
    
                    requestBody += '<Latest>' + blockIds[i] + '</Latest>';
    
                }
    
                requestBody += '</BlockList>';
    
                  console.log(requestBody);
    
                $.ajax({
    
                    url: uri,
    
                    type: "PUT",
    
                    data: requestBody,
    
                    beforeSend: function (xhr) {
    
                          xhr.setRequestHeader('x-ms-blob-content-type', selectedFile.type);
    
                          xhr.setRequestHeader('Content-Length', requestBody.length);
    
                    },
    
                    success: function (data, status) {
    
                        console.log(data);
    
                          console.log(status);
    
                    },
    
                    error: function (xhr, desc, err)   {
    
                          console.log(desc);
    
                          console.log(err);
    
                    }
    
                });
    
     
    
            }
    
            function pad(number, length) {
    
                var str = '' + number;
    
                while (str.length < length) {
    
                    str = '0' + str;
    
                }
    
                return str;
    
            }
    
        </script>
    
    </head>
    
    <body>
    
        <form>
    
            <div style="margin-left: 20px;">
    
                <h1>File Uploader</h1>
    
                <p>
    
                    <strong>SAS URI</strong>:
    
                    <br />
    
                    <span class="input-control text">
    
                        <input type="text" id="sasUrl" style=" 50%"
    
                               value="" />
    
                    </span>
    
                </p>
    
                <p>
    
                    <strong>File To Upload</strong>:
    
                    <br />
    
                    <span class="input-control text">
    
                        <input type="file" id="file" name="file" style=" 50%" />
    
                    </span>
    
                </p>
    
                <div id="output">
    
     
    
                    <strong>File Properties:</strong>
    
                    <br />
    
                    <p>
    
                        Name: <span id="fileName"></span>
    
                    </p>
    
                    <p>
    
                        File Size: <span id="fileSize"></span> bytes.
    
                    </p>
    
                    <p>
    
                        File Type: <span id="fileType"></span>
    
                    </p>
    
                    <p>
    
                        <input type="button" value="Upload File" onclick="uploadFileInBlocks()" />
    
                    </p>
    
                    <p>
    
                        <strong>Progress</strong>: <span id="fileUploadProgress">0.00 %</span>
    
                    </p>
    
                </div>
    
            </div>
    
            <div>
    
            </div>
    
        </form>
    
    </body>
    
    </html>
    View Code

    代码主要是将文件切成小块,并使用Put blob操作上传相应的小块,最后使用Put blob list将上传的各个小块组成资源文件。

  • 相关阅读:
    【js】实现输入框不允许输入某些特殊字符
    springboot集成druid实现数据源监控
    SpringBoot整合Druid并配置数据源监控
    SpringBoot集成Druid实现数据源管理和监控
    同一个catch字句中捕获多个java异常
    【JWT】JSON Web Token原理与实现
    行级锁实验:sql语句条件中的索引对锁的影响
    什么是乐观锁,什么是悲观锁,如何实现
    Linux命令与文件的查找which、wheris、locate、find
    vi编辑器永久设置行号、缩进
  • 原文地址:https://www.cnblogs.com/akingyao/p/4956285.html
Copyright © 2011-2022 走看看