对一些前端工程师来讲,使用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="width: 50%"

                           value="" />

                </span>

            </p>

            <p>

                <strong>File To Upload</strong>:

                <br />

                <span class="input-control text">

                    <input type="file" id="file" name="file" style="width: 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>

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

Javascript 上传文件到Azure存储的更多相关文章

  1. django 用户上传文件media的存储访问配置1

    1. 首先新建文件夹media  后 在项目setting中具体配置: MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media ...

  2. javascript 上传文件相关 (5) Blob 对象

    这一系列文章都讲述的是关于使用 JavaScript 操作文件相关的知识,其中最重要的是 File 对象,而实际上 file 对象只是 blob 对象的一个更具体的版本,blob 存储着大量的二进制数 ...

  3. 微信小程序云开发-云存储-上传文件(图片/视频)到云存储 精简代码

    说明 图片/视频这类文件是从客户端会话选择文件. 一.wxml文件添加if切换显示 <!--上传文件到云存储--> <button bindtap="chooseImg&q ...

  4. 利用jquery.form实现异步上传文件

    实现原理 目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传.思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上 ...

  5. RN 上传文件到以及上传文件到七牛云(初步)

    本文将介绍: 如何使用原生 Javascript 上传文件 如何使用七牛云 SDK 上传文件到七牛云 在 App 中文件上传是一个非常重要的需求,但是翻遍 React Naitve 的官方文档没有发现 ...

  6. 使用XWAF框架(2)——上传文件

    XWAF提供了上传文件的HttpFileUploader工具类,具备强大的多文件上传.文件类型过滤.文件大小限制.存储目录设置.文件名称更改等功能,简化了Web应用开发的编程工作. 它能同时解析表单参 ...

  7. Servlet 表单及上传文件

    // 文件路径 D:\ApacheServer\web_java\HelloWorld\src\com\test\TestServletForm.java package com.test; impo ...

  8. app端上传文件至服务器后台,web端上传文件存储到服务器

    1.android前端发送服务器请求 在spring-mvc.xml 将过滤屏蔽(如果不屏蔽 ,文件流为空) <!-- <bean id="multipartResolver&q ...

  9. c#上传文件并将word pdf转化成txt存储并将内容写入数据库

    c#上传文件并将word pdf转化成txt存储并将内容写入数据库 using System; using System.Data; using System.Configuration; using ...

随机推荐

  1. 基于Halcon的一维条码识别技巧

    Bar Code 条形码 1.clear_all_bar_code_models    清除所有条形码模型释放内存clear_all_bar_code_models( : : : )2.clear_b ...

  2. [故障及解决]SoundPool没有声音

    问题描述:使用SoundPool类进行播放声音时,在手机上没有声音. 问题代码: /** * 声音播放 */ private void playSound() { SoundPool soundPoo ...

  3. 国庆前执行更新承诺SO交期 FP_SO2SAP

    每年9月20日到30号执行以下程序:创建日期为昨天的订单,且承诺交期为10月1到3号,则承诺交期需加7天:创建日期为昨天的订单, 承诺交期为4号到11月1日,承诺交期需加4天 存储过程:FP_SO2S ...

  4. Codeforces 919F——A Game With Numbers

    转自大佬博客:https://www.cnblogs.com/NaVi-Awson/p/8405966.html; 题意 两个人 Van♂ 游戏,每人手上各有 8'>88 张牌,牌上数字均为 [ ...

  5. nohup 无发后台运行

      用nohup命令让Linux下程序永远在后台执行 [ 2006-5-13 22:31:54 | By: 牧云 ]   Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在 ...

  6. linux的deamon后台运行

    有的时候需要将程序一直跑在后台,比如一些服务类代码,或者一些监控类代码.使用deamon是正确的一种思路. 以前我们在看<unix环境高级编程>的时候,有专门的整章详细介绍如何编写一个后台 ...

  7. 为什么rand和srand总是同时出现?

    如果没有srand,那么rand在我电脑上运行每次返回的随机数是一样的.如果如果先调用srand,而且srand的参数不一样,那么最后产生的随机数就会不一样?那怎么然srand的参数是不一样的呢? 是 ...

  8. 31.SUM() 函数

    SUM() 函数 SUM 函数返回数值列的总数(总额). SQL SUM() 语法 SELECT SUM(column_name) FROM table_name SQL SUM() 实例 我们拥有下 ...

  9. wamp安装两个,数据库丢了,怎么办

    wampserver3.*下载了好几天一直没有安装,今天发现必须安装,已升级自己的php版本,不过也饿可以自己手动配置PHP版本,既然有安装包就算了吧,当安装完后,发现忘记备份自己的数据库了,幸好之前 ...

  10. laravel与front-end

    准备工作 在此之前要安装node  . npm .这里安装node . npm 就不介绍了,百度一大把. 安装所有的npm依赖包 //进入项目的根目录 npm install 安装完后会出现一个nod ...