使用SAS和JavaScript前端上传Azure Bolb大文件
问题描述:
Azure Storage Rest API提供了对于大文件分块上传方法,分别使用Put Block和Put Block List实现相关功能
参考链接:
Code Sample
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>File Uploader</title>
<script src="http://code.jquery.com/jquery-1.4.1.js"></script>
<link rel="stylesheet" href="css/modern.css" />
<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);
//xhr.setRequestHeader('x-ms-blob-content-md5', "OcEHvHuHGvmhdZ5vBtxx0Q=="); //设置组合后的blob的md5值,并不会做校验
},
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>
注意事项
- MD5值计算方法
- 完整项目GitHub网址
- 该示例并未进行MD5值的校验操作,如果需要校验需要在请求头中添加Content-MD5参数,Put Block List并不提供对上传完成后完整blob的校验,只能通过x-ms-blob-content-md5设置blob的值,否则后台默认并不会自动生成MD5值
使用SAS和JavaScript前端上传Azure Bolb大文件的更多相关文章
- 20160113006 asp.net实现ftp上传代码(解决大文件上传问题)
using System;using System.Configuration;using System.Data;using System.Linq;using System.Web;using S ...
- 如何免费上传4G以上大文件至百度云网盘
百度云网盘的容量高达2048G,因而如今使用百度云网盘的用户也越来越多, 但是百度云中如果要上传超过4G的大文件,必须要升级VIP才行,但这需要收费.那么,超过4G以上的大文件我们该怎样上传到百度云呢 ...
- ASPCMS不能上传2M以上大文件修改!
\admin_aspcms\editor\upload.asp修改80行左右maxattachsize=xxxxxxxx'最大上传大小,默认是2M前提是IIS上传大小已修 其他有关IIS方面的修改: ...
- git上传超过100m大文件
1.git出错如下错误时 执行如下可解决错误: git rm --cache '大文件路径' git commit --amend -CHEAD git push 2.当必须上传大文件时.需借助git ...
- 精讲RestTemplate第6篇-文件上传下载与大文件流式下载
本文是精讲RestTemplate第6篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 前端上传组件Plupload使用指南
我之前写过一篇文章<文件上传利器SWFUpload使用指南>,里面介绍了上传组件SWFUpload的使用方法,但现在随着html5技术的逐渐推广和普及,再去使用以flash为上传手段的SW ...
- web api 如何通过接收文件流的方式,接收客户端及前端上传的文件
服务端接收文件流代码: public async Task<HttpResponseMessage> ReceiveFileByStream() { var stream = HttpCo ...
- django-form.errors和前端上传文件
一.上传文件: 在相应的模型里面定义`FileField`或者是`ImageField`类型的字段,并且1.设置好`upload_to`参数来指定上传的路径. class User(models.Mo ...
- atitit.javascript js 上传文件的本地预览
atitit.javascript js 上传文件的本地预览 1. .URL.createObjectURL 1 1.1. 吊销所有使用 URL.createObjectURL 而创建的 URL,以 ...
随机推荐
- Linux服务器学习(一)
一.首先连接服务器 下载一个windows下连接linux的ssh工具,我这里用的putty.一次填入HostName(主机名,可以是服务器域名也可以是对应的ip).Port(端口号默认为22).Co ...
- Windows远程linux服务器执行shell命令
一.前言 借用百度百科关于putty的描述:PuTTY是一个Telnet.SSH.rlogin.纯TCP以及串行接口连接软件.较早的版本仅支持Windows平台,在最近的版本中开始支持各类Unix平台 ...
- hibernate 使用枚举字段的最佳实践
枚举类虽然很简单,但是却往往是系统中业务逻辑最集中最复杂的地方.本文将会分享我们项目中基于hibernate的枚举类使用规范,包含数据库中枚举列数据类型.注释.枚举列与枚举类的映射等. 一.枚举类定义 ...
- tcpdump使用方法小结
在进行网络测试的时候,我们经常需要进行抓包的工作,当然有许多测试工具可以使用,比如sniffer, ethreal等.但最为方便和简单得就非TCPDump莫属. Linux的发行版里基本都包括了这个工 ...
- 学生成绩管理系统——C语言实现
一.功能实现: 0.浏览学生信息 1.输入学生信息 2.增加学生信息 3.修改学生信息 4.删除学生信息 5.按学号查询 6.按班级查询 7.按姓名查询 8.按课堂名称查询 9.按总分高低排序 10. ...
- 终极锁实战:单JVM锁+分布式锁
目录 1.前言 2.单JVM锁 3.分布式锁 4.总结 =========正文分割线================= 1.前言 锁就像一把钥匙,需要加锁的代码就像一个房间.出现互斥操作的场景:多人同 ...
- Android 性能测试——Heap Viewer 工具
Android 性能测试--Heap Viewer 工具 Heap Viewer能做什么? 实时查看App分配的内存大小和空闲内存大小 发现Memory Leaks Heap Viewer使用条件 5 ...
- 实例化bean
从bean.xml中<bean>标签内容可以看出bean其实是一个管理对象的东西,我们只需要修改xml配置文件,就可以改变对象之间的依赖关系,不需要去修改任何源代码.我觉得学习好sprin ...
- easyAR图钉功能实现相关
图钉功能总算做出来了,发现真的是因为没认真看手册导致的=.=[跪 最后的代码很简单,但是过程中看了不少camera/tracker相关的东西,感觉需要整理记录一下 图钉功能记录: 目标:实现用ARCa ...
- 单页面应用(spa)引入百度地图(Cannot read property 'dc' of undefined)
难点介绍 引入百度地图的时候,用原生的获取不到dom节点. ( var mapEle = document.getElementById(testApi): var map = new BMap.Ma ...