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>
)
}
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.
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 (
Related
I've been working on an upload progress bar. The problem is, I can't seem to clean up the motion. It's jumpy, and I think it comes down to not understanding the finer details up the the upload process. What can I do to make this motion smoother?
This script has two movements, progressBarDisp is the target for the upload itself. Then it has a second bar for ajax upon files being processed and receiving a confirmation from the server.
My jumpy item is the progressBarDisp - I can't figure out why it's so jumpy.
$('input[type=file].dicomUpload').on("change", function() {
var files = $(this)[0].files;
//console.log(files);
var theCase = $(this).parent().find('input[name="theCase"]');
var casenum = $(this).parent().find('input[name="casenum"]');
var phase = $(this).parent().find('input[name="phase"]');
var vidnum = $(this).parent().find('input[name="vidNum"]');
processUpload(theCase, casenum, phase, files, vidnum);
});
function processUpload(theCase, casenum, phase, myfiles, vidnum) {
//console.log("Processing: "+vidnum.val());
var progressBox = $('#uploadDicomBox' + casenum.val() + '-' + vidnum.val()).find(".uploadprogress");
progressBox.slideDown();
var progressBarDisp = progressBox.find(".progressBarDisp");
var progressBarComp = progressBox.find(".progressBarComp");
var progressBarText = progressBox.find(".progressText");
progressBarText.text('Processing Upload.');
//run this in two parts - get the file sizes of the acceptable file types
var nBytes = 0;
var uploadedBytes = 0;
var completeBytes = 0;
var tempList = new Array();
$.each(myfiles, function(i, file) {
//console.log(file.name+" -- "+file.name.indexOf("."));
// do any file checking logic here
tempList.push(file);
});
myfiles = tempList;
$.each(myfiles, function(i, file) {
nBytes += file.size;
});
console.log("beginning uploads: " + theCase.val() + ", " + casenum.val() + ", " + phase.val() + ", " + nBytes + ", " + vidnum.val());
//console.log(myfiles);
if (myfiles.length < 1) {
progressBarText.text('No valid file types selected.');
}
//tracking variable
var maxup = 0;
$.each(myfiles, function(i, file) {
//file sizes are going to be an issue for me, these need to be individual file uploads
progressBarText.text('Upload Progress');
// Create a FormData object
var formData = new FormData();
formData.append('casenum', casenum.val());
formData.append('phase', phase.val());
formData.append('theCase', theCase.val());
formData.append('vidnum', vidnum.val());
formData.append('file', file);
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
maxup = Math.max(maxup, evt.loaded);
var percentComplete = (maxup / evt.total) * 100;
//Do something with upload progress here
//console.log("Upload Status: "+evt.loaded+" / "+evt.total+" -- "+((evt.loaded/evt.total)*100)+"%");
progressBarDisp.width(percentComplete + '%');
progressBarText.text('Upload Progress: Uploading ' + myfiles.length + ' files');
if (percentComplete == 100) {
progressBarText.text('Upload Progress: Upload Complete. Now Processing.');
}
}
}, false);
return xhr;
},
type: 'POST',
url: BASE_URL,
cache: false,
contentType: false,
processData: false,
data: formData,
beforeSend: function(xhr) {
uploadedBytes += file.size;
//progressBarDisp.width(((uploadedBytes/nBytes)*100)+'%');
progressBarText.text('Upload Progress: Uploading ' + myfiles.length + ' files');
},
success: function(result) {
console.log(result);
var resJSON = JSON.parse(result);
if (resJSON.status == "success") {
completeBytes += file.size;
processed = Math.round((completeBytes / nBytes) * myfiles.length);
progressBarComp.width(Math.round((processed / myfiles.length) * 100) + '%');
progressBarText.text('Upload Progress: Processed ' + (processed) + ' of ' + myfiles.length + ' files');
/*if(myfiles.length == (i+1)){
progressBarText.text('Upload Progress: Complete');
}
else{
progressBarText.text('Upload Progress: Uploaded '+(i+1)+' of '+myfiles.length+' files');
}
*/
}
},
error: function(err) {
//console.log(err);
uploadedBytes += file.size;
progressBarDisp.width(((uploadedBytes / nBytes) * 100) + '%');
}
});
});
}
I have just javascript and css. But want to show the uploaded file name
Googled a lot
So I have this as css:
.metadata .filename{
font-size: 10px;
color: red;
display: inline-block;
}
and this is the js code:
var messagetext = '';
messagetext += '<span class="metadata">' + '<span class="filename">' + file.name + '</span>';
But if I do a console.log(file.name) then I see the name of the uploaded file in the console.
But I dont see it in the view.
Thank you
this is the whole function:
$('body').on('change', '#upload-input', function () {
var halloText = 'file';
var files = $(this).get(0).files;
if (files.length > 0) {
// create a FormData object which will be sent as the data payload in the
// AJAX request
var formData = new FormData();
// loop through all the selected files and add them to the formData object
for (var i = 0; i < files.length; i++) {
var file = files[i];
var message = buildMessage(myUserId, new Date().toISOString(), '<div class="imagepreview"><canvas id="progress' + imagecounter + '" width="80" height="80"></canvas><img id="image' + imagecounter + '"/></div>', 'sent');
message.classList.add('imagesender');
message.classList.add('imagesender' + imagecounter);
conversation.appendChild(message);
//processImages();
conversation.scrollTop = conversation.scrollHeight;
var myCanvas = document.getElementById('progress' + imagecounter);
var circle = new ProgressCircle({
canvas: myCanvas,
});
var percentComplete = 0.65;
circle.addEntry({
minRadius: 30,
fillColor: 'rgba(0, 0, 0, 0.5)',
progressListener: function () {
return percentComplete; // between 0 and 1
}
});
circle.start(33);
var extn = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();
if (extn == "gif" || extn == "png" || extn == "jpg" || extn == "jpeg") {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.id = imagecounter;
reader.onload = function (e) {
var imageid = imagecounter;
document.getElementById("image" + e.currentTarget.id).src = e.target.result;
};
reader.readAsDataURL(file);
} else {
// No filereader support... so no preview
}
}
imagecounter++;
// add the files to formData object for the data payload
formData.append('uploads[]', file, file.name);
}
formData.append('Token', SessionInfo.ImageToken);
formData.append('RoomId', currentRoom.RoomId);
dbgMessage(formData);
$.ajax({
url: apipath + '/devices/UploadData',
type: 'POST',
data: formData,
processData: false,
contentType: false,
done: function (data) {
},
error: function(jqXHR, textStatus, errorThrown ){
//show error as a message
var message = buildMessage(myUserId, new Date().toISOString(), jqXHR.responseText, 'error');
conversation.appendChild(message);
conversation.scrollTop = conversation.scrollHeight;
},
xhr: function () {
// create an XMLHttpRequest
var xhr = new XMLHttpRequest();
// listen to the 'progress' event
xhr.upload.addEventListener('progress', function (evt) {
if (evt.lengthComputable) {
// calculate the percentage of upload completed
percentComplete = evt.loaded / evt.total;
if (percentComplete == 1) {
var messagetext = '';
messagetext += '<span class="metadata">' + '<span class="filename">' + file.name + '</span>';
// Handle complete
$('.imagesender').hide();
dbgMessage('Upload complete ');
console.log(file.name);
}
}
}, false);
return xhr;
}
});
}
});
So that the file name will be visible in the html view.
if I do this:
$('.messagewrapper').append('<span class="metadata">' + '<span class="filename">' + file.name + '</span>');
Then it works only after I upload file.
But When I refresh the page the image file is not visible anymore
Like this:
if (percentComplete == 1) {
// Handle complete
$('.imagesender').hide();
dbgMessage('Upload complete ');
}
$('.messagewrapper').append("<p>"+ file.name+"</p>")
append based on id like this should work:
$('#messagewrapper').append("<p>"+ file.name+"</p>")
You will append this only when the file is uploaded because it is inside the if statement:
percentComplete = evt.loaded / evt.total;
if (percentComplete == 1){ //==1 means uploaded
//your append is here
So move it outside the if statement.
I have 3 Image or Multiple Images Array whose total size is approx. 29mb or above. I am try to post it on server Side using Ajax with Form data. But It shows error when i try to post large data using FormData in MVC is there any solution. when i try to post data it shows error on client side means go into the request.fail section
This is My Jquery Code
var filess = new Array();
var num = 4;
var IsAlready = false;
$(document).ready(function() {
document.getElementById('pro-image').addEventListener('change', readImage, false);
$( ".preview-images-zone" ).sortable();
$(document).on('click', '.image-cancel', function() {
debugger;
let no = $(this).data('no');
let Id = this.id;
$(".preview-image.preview-show-"+no).remove();
for (var i = 0; i < filess.length; i++) {
debugger;
filess = $.grep(filess, function(value) {
return value.name != Id;
});
}
});
});
function readImage() {
if (window.File && window.FileList && window.FileReader) {
var files = event.target.files;
var output = $(".preview-images-zone");
for (var i = 0; i < files.length; i++) {
$.grep(filess, function (n) {
if (n.name == files[i].name) {
IsAlready = true;
}
})
if (IsAlready)
{
alert("Same Name File Exist");
$("#pro-image").val('');
IsAlready = false;
return false;
}
}
var anyWindow = window.URL || window.webkitURL;
for (var i = 0; i < files.length; i++) {
filess.push(files[i]);
var file = null;
file = files[i];
if (!file.type.match('image')) continue;
var objectUrl = anyWindow.createObjectURL(files[i]);
var html = '<div class="preview-image preview-show-' + num + '" >' +
'<div class="image-cancel" data-no="' + num + '" id="' + files[i].name + '">x</div>' +
'<div class="image-zone"><img id="pro-img-' + num + '" src="' + objectUrl + '"></div>' +
'</div>';
output.append(html);
num = num + 1;
window.URL.revokeObjectURL(files[i]);
}
$("#pro-image").val('');
}
else {
console.log('Browser not support');
}
}
$("#submit").click(function () {
event.preventDefault();
debugger;
var url = "/Administration/CreateAlbum";
var albumName = $("#AlbumName").val();
var albumDescription = $("#AlbumDescription").val();
var IsActive = $("#IsActive").val();
var filess = new Array();
var data = new FormData();
data.append('albumName', albumName);
data.append('albumDescription', albumDescription);
data.append('IsActive', IsActive);
$("#submit").prop("disabled", true);
for (var i = 0; i < filess.length; i++) {
data.append('image', filess[i] );
}
var request = $.ajax({
url: url,
enctype: 'multipart/form-data',
type: 'POST',
processData: false,
contentType: false,
cache: false,
timeout: 600000,
data: data
});
request.done(function (response) {
$("#resultCode").html(response.ResultCode);
$("#resultMessage").html(response.ResultMessage);
$('#reasonCode').val("");
$('#quantity').val("");
$('#inventoryCode').val("");
$('#unitCost').val("");
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
As discussed, you need to set the maxAllowedContentLength in the web.config
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="YOUR SIZE" />
</requestFiltering>
</security>
</system.webServer>
thanks
For large file upload.
ini_set('upload_max_filesize', '10M'); ini_set('post_max_size', '10M');
your files array is blank and no need to specify enctype. Here in Ajax
var files = array();
if you have multiple files,then append like
data.append('image[]', filess[i] );
var filess = new Array();
var num = 4;
var IsAlready = false;
$(document).ready(function() {
document.getElementById('pro-image').addEventListener('change', readImage, false);
$( ".preview-images-zone" ).sortable();
$(document).on('click', '.image-cancel', function() {
debugger;
let no = $(this).data('no');
let Id = this.id;
$(".preview-image.preview-show-"+no).remove();
for (var i = 0; i < filess.length; i++) {
debugger;
filess = $.grep(filess, function(value) {
return value.name != Id;
});
}
});
});
function readImage() {
if (window.File && window.FileList && window.FileReader) {
var files = event.target.files;
var output = $(".preview-images-zone");
for (var i = 0; i < files.length; i++) {
$.grep(filess, function (n) {
if (n.name == files[i].name) {
IsAlready = true;
}
})
if (IsAlready)
{
alert("Same Name File Exist");
$("#pro-image").val('');
IsAlready = false;
return false;
}
}
var anyWindow = window.URL || window.webkitURL;
for (var i = 0; i < files.length; i++) {
filess.push(files[i]);
var file = null;
file = files[i];
if (!file.type.match('image')) continue;
var objectUrl = anyWindow.createObjectURL(files[i]);
var html = '<div class="preview-image preview-show-' + num + '" >' +
'<div class="image-cancel" data-no="' + num + '" id="' + files[i].name + '">x</div>' +
'<div class="image-zone"><img id="pro-img-' + num + '" src="' + objectUrl + '"></div>' +
'</div>';
output.append(html);
num = num + 1;
window.URL.revokeObjectURL(files[i]);
}
$("#pro-image").val('');
}
else {
console.log('Browser not support');
}
}
$("#submit").click(function () {
event.preventDefault();
debugger;
var url = "/Administration/CreateAlbum";
var albumName = $("#AlbumName").val();
var albumDescription = $("#AlbumDescription").val();
var IsActive = $("#IsActive").val();
var filess = new Array();
var data = new FormData();
data.append('albumName', albumName);
data.append('albumDescription', albumDescription);
data.append('IsActive', IsActive);
$("#submit").prop("disabled", true);
for (var i = 0; i < filess.length; i++) {
data.append('image', filess[i] );
}
var request = $.ajax({
url: url,
enctype: 'multipart/form-data',
type: 'POST',
processData: false,
contentType: false,
cache: false,
timeout: 600000,
data: data
});
request.done(function (response) {
$("#resultCode").html(response.ResultCode);
$("#resultMessage").html(response.ResultMessage);
$('#reasonCode').val("");
$('#quantity').val("");
$('#inventoryCode').val("");
$('#unitCost').val("");
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
I am trying to use the FileReader API to upload files to a server.
File uploading works well. Although I am uploading the file in chunks, but the memory used by the FormData object is not freed after the upload, that is uploading a large file crashes the browser.
Here's my code:
I was wondering what it is that I am doing wrong?
function uid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function parseFile(file) {
var fileSize = file.size;
var chunkSize = 10 * 1024 * 1024; // bytes
var offset = 0;
var block = null;
var doUpload = null;
var sendEndSignal = null;
var id = uid();
var chunks = {};
var r = new FileReader();
var xhr = new XMLHttpRequest();
var fd = new FormData();
var foo = function (evt) {
}
block = function (_offset, length, _file) {
var blob = _file.slice(_offset, length + _offset);
r.onload = foo;
r.onloadend = (
function (file, id, off) {
return function (evt) {
if (evt.target.error == null) {
off += chunkSize;
if (off >= fileSize) {
console.log("Done reading file");
return;
}
var fnc = block;
doUpload(file, evt.target.result, id, Math.floor(off / chunkSize), chunks, chunkSize, block, off);
} else {
alert("Read error: " + evt.target.error);
return;
}
}
})(_file, id, _offset);
r.readAsDataURL(blob);
}
doUpload = function (file, data, id, chunk, chunks, chunkSize,nx,off) {
xhr = new XMLHttpRequest();
fd = new FormData();
fd.append(file.name + "-----" + id + "-----" + String(chunk), data);
xhr.open("post", "Handler1.ashx", true);
xhr.send(fd);
xhr.addEventListener('readystatechange',
function (e) {
if (this.readyState === 4) {
chunks[Math.floor(chunk)] = 1;
var cnt = 0;
var cntDone = 0;
for (var key in chunks) {
if (chunks.hasOwnProperty(key)) {
cnt++;
if (chunks[key] === 1)
cntDone += 1;
}
}
if (nx)
nx(off,chunkSize,file);
if (cnt === Math.ceil(file.size / chunkSize) && cnt === cntDone)
sendEndSignal(file, id, cnt - 1);
}
});
}
sendEndSignal = function (file, id, num) {
fd = new FormData();
xhr = new XMLHttpRequest();
fd.append("Done-----" + file.name + "-----" + id, num);
xhr.open("post", "Handler1.ashx", true);
xhr.send(fd);
}
block(offset, chunkSize, file);
}
Thank you.
Update:
I solved my problem using jquery post instead of XMLHttpRequest and FormData.
Here's What I have done:
<script type="text/javascript">
function uid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function parseFile(file,index) {
var fileSize = file.size;
var chunkSize = 10 * 1024 * 1024; // bytes
var offset = 0;
var block = null;
var doUpload = null;
var sendEndSignal = null;
var id = uid();
var chunks = {};
var r = new FileReader();
var foo = function (evt) {
}
block = function (_offset, length, _file) {
var blob = _file.slice(_offset, length + _offset);
var div = document.getElementById("file-" + String(index));
div.innerHTML = div.innerHTML + "*";
r.onload = foo;
r.onloadend = (
function (file, id, off) {
return function (evt) {
if (evt.target.error == null) {
doUpload(file, evt.target.result, id, Math.floor(off / chunkSize), chunks, chunkSize, block, off,index);
} else {
alert("Read error: " + evt.target.error);
return;
}
}
})(_file, id, _offset);
r.readAsDataURL(blob);
}
doUpload = function (file, data, id, chunk, chunks, chunkSize, nx, off,ind) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebForm1.aspx/ProcessData",
data: "{'data':'" + data + "','name':'" + file.name + "-----" + id + "-----" + String(chunk) + "'}",
success: function (dd) {
debugger;
chunks[Math.floor(chunk)] = 1;
var cnt = 0;
var cntDone = 0;
for (var key in chunks) {
if (chunks.hasOwnProperty(key)) {
cnt++;
if (chunks[key] === 1)
cntDone += 1;
}
}
if (cnt === Math.ceil(file.size / chunkSize) && cnt === cntDone)
sendEndSignal(file, id, cnt - 1,ind);
if (nx) {
debugger;
off += chunkSize;
if (off >= file.size) {
return;
}
nx(off, chunkSize, file);
}
},
error: function (result) {
alert(JSON.stringify(result));
}
});
}
sendEndSignal = function (file, id, num,ind) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebForm1.aspx/ProcessData",
data: "{'data':'" + num + "','name':'" + "Done-----" + file.name + "-----" + id + "'}",
success: function (dd) {
var div = document.getElementById("file-" + String(ind));
div.innerHTML = "<b>" + file.name + "</b> => DONE!!!!";
},
error: function (result) {
alert(JSON.stringify(result));
}
});
}
block(offset, chunkSize, file);
}
function xx(inp) {
var i = 0;
var file;
var node = document.getElementById("dupl");
debugger;
while (node.hasChildNodes())
node.removeChild(node.lastChild);
for (i = 0; i < inp.files.length; i++) {
file = inp.files[i];
var dd = document.createElement("div");
dd.id = "file-" + String(i);
dd.innerHTML = "<b>" + file.name + "</b>";
document.getElementById("dupl").appendChild(dd);
}
for (i = 0; i < inp.files.length; i++) {
file = inp.files[i];
parseFile(file,i);
}
}
</script>
Hope It will be useful for someone.
I have this code in a js file which I am including in Default page to Create cookies at the clients' browser and using it in the Thankyou page to invoke my web service to track payment transactions.
// Read a page's GET URL variables and return them as an associative array.
$(document).ready(function () {
$.extend({
getUrlVars: function () {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
},
getUrlVar: function (name) {
return $.getUrlVars()[name];
},
getCookie: function (name) {
var dc = document.cookie;
var prefix = name + "=";
var begin = dc.indexOf("; " + prefix);
if (begin == -1) {
begin = dc.indexOf(prefix);
if (begin != 0) return null;
}
else {
begin += 2;
var end = document.cookie.indexOf(";", begin);
if (end == -1) {
end = dc.length;
}
}
return unescape(dc.substring(begin + prefix.length, end));
}
});
{
var cookieStart, cookieEnd, cookieValue, UserGuid, productId, AffiliationURL, PricePerUnit, commissionAmount;
// Get object of URL parameters
if ($.getUrlVars() != null) {
var allVars = $.getUrlVars();
}
// Getting URL var by its name
//Now check if the user is from Seek Site??
//If this is not null that means the user is Refered from Seek Site
if ($.getUrlVar('clientId') != null) {
UserGuid = $.getUrlVar('clientId');
if ($.getUrlVar('productId') != null) {
productId = $.getUrlVar('productId');
}
if ($.getUrlVar('AffiliationURL') != null) {
AffiliationURL = $.getUrlVar('AffiliationURL');
}
if ($.getUrlVar('PricePerUnit') != null) {
PricePerUnit = $.getUrlVar('PricePerUnit');
}
if ($.getUrlVar('commissionAmount') != null) {
commissionAmount = $.getUrlVar('commissionAmount');
}
//Now Create the cookie for the user
var myCookie = $.getCookie("ReferedCookie");
alert(myCookie);
if (myCookie != null) {
// cookie exists
cookieStart = myCookie.indexOf("clientId=");
//alert(cookieStart = cookieStart + "ReferedCookie=".length);
cookieEnd = myCookie.indexOf(";", cookieStart);
//if there is no occurence of the semicolon character
//cookieEnd takes the length of the document.cookie property
if (cookieEnd == -1) cookieEnd = myCookie.length;
cookieValue = myCookie.substring(cookieStart, cookieEnd);
// check the Product Id
if (cookieValue.indexOf(productId + "&", "productId=") != -1) {
// that means the User clicked on the same Product again and there is already a cookie Exists for that product
alert("User clicked on the same Product again");
}
else {
// The Product Id is different ,We are going to add that product value as string to the cookie
}
}
else {
// Create Cookie
var expiryDate = new Date();
expiryDate.setTime(expiryDate.setDate(expiryDate.getDate() + 365)); // 365 days
document.cookie = "ReferedCookie=" + "clientId=" + UserGuid + "&productId=" + productId + "&AffiliationURL=" + AffiliationURL + "&PricePerUnit=" + PricePerUnit + "&commissionAmount=" + commissionAmount + ";" + "expires=" + expiryDate.toGMTString() + ";";
}
}
}});
And Here the Code which I want to run at Thankyou page but it runs in IE9 (at time I dnt know why???)
{
var cookieStart, cookieEnd, cookieValue, UserGuid, productId, AffiliationURL, PricePerUnit, commissionAmount;
$(window).load(function (e) {
e.preventDefault();
$.extend({
readCookie: function (name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
});
var x = new Array(3);
cookieValue = $.readCookie("ReferedCookie");
var s = 0;
var pos = cookieValue.indexOf("&");
while (pos > -1) {
x[s] = pos;
pos = cookieValue.indexOf("&", pos + 1);
// alert(x[s]);
s++;
}
var c1 = cookieValue.indexOf("clientId=");
alert(UserGuid = cookieValue.substring(c1 + 9, x[0]));
var p1 = cookieValue.indexOf("productId=");
alert(productId = cookieValue.substring(p1 + 10, x[1]));
var A1 = cookieValue.indexOf("AffiliationURL=");
alert(AffiliationURL = cookieValue.substring(A1 + 15, x[2]));
var pp1 = cookieValue.indexOf("PricePerUnit=");
alert(PricePerUnit = cookieValue.substring(pp1 + 13, x[3]));
var com1 = cookieValue.indexOf("commissionAmount=");
alert(commissionAmount = cookieValue.substring(com1 + 17));
var ServiceURL = 'http://localhost:12445/Service/TrackPayment.asmx/InsertCommissionRecord';
// var d = '{"ProductID": "' + productId + '" , "AffiliationURL": "' + AffiliationURL + '" , "Quantitiy": "' + 15 + '" , "PricePerUnit": "' + PricePerUnit + '" , "commissionAmount": "' + commissionAmount + '"}';
var d = '{"ProductID":"1","AffiliationURL":"1","Quantitiy":"1","PricePerUnit":"1","commissionAmount":"1"}';
alert(d);
$.ajax({
type: 'POST',
data: d,
url: ServiceURL,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success:
function (data, textStatus, XMLHttpRequest) {
alert(data);
alert(textStatus);
alert(XMLHttpRequest);
},
error:
function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
alert(errorThrown);
}
});
});}
In firebug console it show data.d is null
Kindly help me out and please point out where I am going wrong.
Thanks
JS:
$.ajax({
type: 'POST',
data: {'d': d},
url: ServiceURL,
dataType: 'json',
success:
function (data, textStatus, XMLHttpRequest) {
alert(data.ProductID); // returns '1'
},
error:
function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
alert(errorThrown);
}
});
test.php:
$data = json_decode($_POST['d']);
echo json_encode($data);