Reputation: 113
I have read a lot of already existing questions on uploading a file to azure storage directly from client-side/browser. The one I am implementing is from this blog by gaurav mantri. In this blog he splits the SAS url into path and query and then append file name to the path and then stiched the query again to it. I have SAS url which doesn't have any query. I just have url like this
This SAS url has the file name also appended in it. In the blog he appends blockId and blockList etc. Do it really need to do that? If not how should I make PUT request? Just using my SAS url would work?
Update: I have included query parameter (SAS token) as "URL?SAS-TOKEN". Now I am getting error like this
Error
dll.vendor.js:44368 PUT https://triggerbackendnormal.blob.core.windows.net/backend-media/a07d312c-6…Vhgoxw/NmD2AeSo4qVhBntrI04xJo1tsqfKJA/7bmQ%3D&comp=block&blockid=undefined 400 (Value for one of the query parameters specified in the request URI is invalid.)CORS
CORS Rules Setup in portal:
JS code:
handleFileSelect(e) {
var that = this
maxBlockSize = 256 * 1024;
currentFilePointer = 0;
totalBytesRemaining = 0;
files = e.target.files;
selectedFile = files[0];
console.log(selectedFile.name)
console.log(selectedFile.size)
console.log(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);
// $("#fileName").text(selectedFile.name);
// $("#fileSize").text(selectedFile.size);
// $("#fileType").text(selectedFile.type);
var baseUrl = 'https://example.blob.core.windows.net/backend-m/a07d312c-6e7a-4281-9e4f-050f5afc4609.mp4?sr=b&se=2017-05-04T15%3A07%3A30Z&sp=w&sv=2016-05-31&sig=SVhgoxw/NmD2AeSo4qVhBntrI04xJo1qfKJA/7bmQ%3D'
submitUri = baseUrl
console.log(submitUri);
this.uploadFileInBlocks();
}
//var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
//currentFilePointer =+ maxBlockSize;
uploadFileInBlocks() {
if (totalBytesRemaining > 0) {
console.log("current file pointer = " + currentFilePointer + " bytes read = " + maxBlockSize);
var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
var blockId = blockIdPrefix + this.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 {
this.commitBlockList();
}
}
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);
}
});
}
pad(number, length) {
var str = '' + number;
while (str.length < length) {
str = '0' + str;
}
return str;
}
render(){
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);
console.log(percentComplete)
this.uploadFileInBlocks();
},
error: function(xhr, desc, err) {
console.log(desc);
console.log(err);
}
});
}
};
return (
<label htmlFor='myInput'>
<input id="myInput" type="file" ref={(ref) => this.upload = ref} style={{visibility: 'hidden'}} onChange={this.handleFileSelect.bind(this)}/>
<FloatingActionButton
className="floatingButton"
backgroundColor='#fb802a'
onClick={(e) => this.upload.click() }>
<ContentAdd />
</FloatingActionButton>
</label>
)
}
Upvotes: 1
Views: 1128
Reputation: 113
For ReactJS, this is how it should be done
handleFileSelect(e) {
var that = this
maxBlockSize = 256 * 1024;
currentFilePointer = 0;
totalBytesRemaining = 0;
files = e.target.files;
selectedFile = files[0];
console.log(selectedFile.name)
console.log(selectedFile.size)
console.log(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);
// $("#fileName").text(selectedFile.name);
// $("#fileSize").text(selectedFile.size);
// $("#fileType").text(selectedFile.type);
var baseUrl = 'https://example.blob.core.windows.net/backend-media/e7581d7b-a59d-47eb-b8aa-6b6799179b36.mp4?sv=2016-05-31&sr=b&se=2017-05-09T18%3A26%3A07Z&sp=w&sig=TlS/a9RgVT/j7BHztjFZSF2L2skno3Sko%3D'
submitUri = baseUrl
console.log(submitUri);
this.uploadFileInBlocks();
}
loadEnd(evt){
var that = this;
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("hi" + status);
bytesUploaded += requestData.length;
var percentComplete = ((parseFloat(bytesUploaded) / parseFloat(selectedFile.size)) * 100).toFixed(2);
console.log(percentComplete)
that.uploadFileInBlocks();
},
error: function(xhr, desc, err) {
console.log(desc);
console.log(err);
}
});
}
}
uploadFileInBlocks() {
if (totalBytesRemaining > 0) {
console.log("current file pointer = " + currentFilePointer + " bytes read = " + maxBlockSize);
var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
var blockId = blockIdPrefix + this.pad(blockIds.length, 6);
console.log("block id = " + blockId);
blockIds.push(btoa(blockId));
reader.readAsArrayBuffer(fileContent);
reader.onloadend = this.loadEnd.bind(this);
currentFilePointer += maxBlockSize;
totalBytesRemaining -= maxBlockSize;
if (totalBytesRemaining < maxBlockSize) {
maxBlockSize = totalBytesRemaining;
}
} else {
this.commitBlockList();
}
}
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("hi" + status);
},
error: function (xhr, desc, err) {
console.log(desc);
console.log(err);
}
});
}
pad(number, length) {
var str = '' + number;
while (str.length < length) {
str = '0' + str;
}
return str;
}
render(){
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);
console.log(percentComplete)
this.uploadFileInBlocks();
},
error: function(xhr, desc, err) {
console.log(desc);
console.log(err);
}
});
}
};
return (
Upvotes: 0
Reputation: 136379
I have SAS url which doesn't have any query. I just have url like this 'https://exapmplename.blob.core.windows.net/backend/a074281-9e4f-050f5afc4609.mp4'
This is not a SAS URL. It is simply a URL for the blob. A SAS URL has Shared Access Signature parameters like sig
, se
, sv
etc. appended to the URL as querystring parameters. I would suggest you create a SAS URL and use that. In order to upload a blob, the SAS URL must have Write
permission.
In the blog he appends blockId and blockList etc. Do it really need to do that?
It depends! If you're uploading blob without splitting the file in blocks using Put Blob
REST API, then you need not do that. However if you need to split the file into blocks and use Put Block
and Put Block List
REST API, then you have to do that.
If not how should I make PUT request?
If your file is small and have good Internet speed, then you really need not split the file in smaller chunks and upload a file in one go using Put Blob
REST API.
Upvotes: 1