Reading Blob of a file in javascript and inserting in database - javascript

I want to read any kind of file from my js code and insert its blob to database in long blob type column. Variable in js is reading blob as string but not as blob.
So I am facing issue if there are special characters like single/double quote etc.
reading code is
function onChooseFile(event, onLoadFileHandler) {
if (typeof window.FileReader !== 'function')
throw ("The file API isn't supported on this browser.");
let input = event.target;
if (!input)
throw ("The browser does not properly implement the event object");
if (!input.files)
throw ("This browser does not support the `files` property of the file input.");
if (!input.files[0])
return undefined;
let file = input.files[0];
let fr = new FileReader();
fr.onload = onLoadFileHandler;
fr.onloadend = function(event) {
if (event.target.readyState == FileReader.DONE) { // DONE == 2
//blobData = event.target.result;
blobData = new Blob([event.target.result], { type: fileType });
console.log(blobData);
console.log(typeof(blobData));
console.log(blobData instanceof Blob)
console.log("-------------------------------------------------");
blobString = ab2str(event.target.result);
console.log(blobData);
alert("file read complete "+blobData.length);
}
};
document.getElementById('inputHeader').value = file.name;
fileName = file.name;
fileType = file.type;
fileExtension = fileName.split(".").pop();
fr.readAsBinaryString(file);
}
Writing Code is
dataservice.openDocument(document_version_id)
.done(function (reply) {
fileExtension = fileName.split(".").pop();
switch(fileExtension.toLowerCase()){
case "doc":
case "docx":
fileType = "application/msword";
break;
case "pdf":
fileType = "application/pdf";
break;
case "xls":
case "xlsx" :
fileType = "application/vnd.ms-excel";
break;
}
var blob = new Blob([reply.RECORD_DATA.LONG_BLOB], { type: fileType });
saveAs(blob, 'C:/OutputFile/hello.'+fileExtension);
deferred.resolve();
}).fail(function (error) {
alert("failure in getting document");
deferred.reject();
});
});
Please help, how to achieve this.
Thanks

Related

JavaScript FileReader returns "undefined"

I was trying to Base64 encode a user-provided file with JS. This is my code:
let image = document.getElementById('image').files[0];
if (!image) {
alert('No images have been provided!');
return;
}
let blob = new Blob([image], { type: 'image/png' });
let reader = new FileReader;
reader.addEventListener('load', loadEvent => {
let base64EncodedImage = reader.result
.replace('data:', '');
});
Problem is that reader.readAsDataURL(blob) always returns undefined.

is it possible to convert uploadcollection's object into a xstring?

Using the sapui5 uploadcollection to upload files in the frontend and then sending them through ajax with a post request...
I need to know how to convert te returned object from the uploadcollection control into a xstring, so then I can send that xstring (that contains the file content) To a sap gateway by using ajax post method.
Any idea how could I do this?
Right now I'm sending files by using the uploadcollection, once I upload an attachment, the control returns an object that represents the file content.
I'm trying to make this object a xstring by using filereader:
//obtiene archivo
var file = files[i];
//Convierte archivo en binario
var reader = new FileReader();
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result;
var base64 = btoa(binaryString);
var base64file;
if(typeof base64file == "undefined" || typeof base64file == null){
base64file = base64;
}else{
base64file = base64file +'new'+base64;
}
};
reader.readAsBinaryString(file);
console.log(file)
But this work only with files of type image, the others like pdf, .doc etc etc give the following error when I try to send them with ajax.
"The Data Services Request could not be understood due to malformed syntax".
Any idea how can I send convert these files into a xstring data?
Take a look at this example. Hope this helps.
View
<u:FileUploader change="onChange" fileType="pdf" mimeType="pdf" buttonText="Upload" />
Controller
convertBinaryToHex: function(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), function(x) {
return ("00" + x.toString(16)).slice(-2);
}).join("");
},
onChange: function(oEvent){
var that = this;
var reader = new FileReader();
var file = oEvent.getParameter("files")[0];
reader.onload = function(e) {
var raw = e.target.result;
var hexString = that.convertBinaryToHex(raw).toUpperCase();
// DO YOUR THING HERE
};
reader.onerror = function() {
sap.m.MessageToast.show("Error occured when uploading file");
};
reader.readAsArrayBuffer(file);
},
I figured it out by filling an array everytime that a file was uploaded through the control,
change: function(oEvent) {
//Get file content
file = oEvent.getParameter("files")[0];
//Prepare data for slug
fixname = file.name;
filename = fixname.substring(0, fixname.indexOf("."));
extension = fixname.substring(fixname.indexOf(".") + 1);
//fill array with uploaded file
var fileData = {
file: file,
filename: filename,
extension: extension
}
fileArray.push(fileData);
},
and then I did a loop over that array to post every single file I keept there by using ajax method post.
$.each(fileArray, function(j, valor) {
//get file
file = fileArray[j].file;
//get file lenght
var numfiles = fileArray.length;
//Convert file to binary
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(evt) {
fileString = evt.target.result;
//get and make slug
filename = fileArray[j].filename;
extension = fileArray[j].extension;
slug = documento + '/' + filename + '/' + extension;
//User url service
var sUrlUpload = "sap url";
runs++;
//Post files
jQuery.ajax({});
}
});

File uploaded does not upload if the file name has parenthesis ()

I have a FileUpload control where I upload PDF files and they get saved to a folder, the file path gets saved to the database.
The problem is when I upload a file which contains parenthesis () as part of the file name, it returns undefined. This only happens if the file name has parenthesis () , if it does not have parenthesis () it uploads fine.
This is my code
var filePaths;
function UploadFile() {
var fileUpload = document.getElementById("fuPDFupload");
var regex = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(.jpg|.png|.pdf)$");
if (regex.test(fileUpload.value.toLowerCase())) {
//Check whether HTML5 is supported.
if (typeof (fileUpload.files) != "undefined") {
//Initiate the FileReader object.
var reader = new FileReader();
//Read the contents of Image File.
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
//Initiate the JavaScript Image object.
var image = new Image();
//Set the Base64 string return from FileReader as source.
image.src = e.target.result;
var fileUpload = $("#fuPDFupload").get(0);
var files = fileUpload.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append(files[i].name, files[i]);
}
$.ajax({
url: "FileUploadHandler.ashx",
type: "POST",
data: data,
contentType: false,
processData: false,
success: function (result) {
filePaths = result;
//Save to DB
UpdateSchedule();
},
error: function (err) {
}
});
return true;
};
} else {
alert("This browser does not support HTML5.");
return false;
}
} else {
return false;
}
}
FileUploadHandler Code:
public class FileUploadHandler : IHttpHandler {
public void ProcessRequest(HttpContext context)
{
if (context.Request.Files.Count > 0)
{
string filePaths = Guid.NewGuid().ToString() + ".pdf";
HttpPostedFile file = context.Request.Files[0];
string path = context.Server.MapPath("~/QfrencyInvoices/" + filePaths);
file.SaveAs(path);
context.Response.ContentType = "text/plain";
context.Response.Write(filePaths);
}
}
public bool IsReusable {
get {
return false;
}
}
}
I believe that the problem might be happening because the Regex expression is incorrect but I have not been able to fix it.
Please assist me how I can upload files that have parenthesis () as part of the file name. Thank you.
Just leave next regex new RegExp("(\.(jpg|png|pdf)$", "i");. It checks that filename has extension jpg, png or pdf. Text case does not matter so "i" was added as the second parameter.
You can learn regular expressions on https://regexone.com/

MVC Asp.net zip file download

I have some code in an MVC project that creates a zip file and sends it to the browser. Everything works when I manually enter the URL in the browser, but if I click on the link in the page to get the download, I get a file of a different size and Windows cannot open it.
So, if I manually enter something like this:
http://localhost/fms-ui/File/DownloadZipFile/?id=10&filename=DST-2015-11-14_04_04_04
I get a zip file of 167 bytes and it open fine.
If I click on the link in the page, I get a file of 180 bytes and Windows says the file is corrupted. Hun?
My one stipulation is that I cannot use an external library. Due to politics I must use the library provided with .Net Framework 4.5 (static ZipFile class).
Code:
public FileContentResult DownloadZipFile(int id, string filename)
{
/*
* 1 - get fileset info
* 2 - get temp file name
* 3 - create zip file under temp name
* 4- return file
*/
QuesterTangent.Wayside.FileServices.FileSet sInfo = new QuesterTangent.Wayside.FileServices.FileSet(id);
string path = Path.Combine(sInfo.BasePath);
string tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".zip");
ZipFile.CreateFromDirectory(path, tempPath);
byte[] fileBytes = System.IO.File.ReadAllBytes(tempPath);
//System.IO.File.Delete(tempPath); Commented so I can compare the files
filename = filename + ".zip";
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(fileBytes, "application/zip");
}
I've tried this with and without AppendHeader and with various contentTypes, but it doesn't seem to effect the outcome.
Here is the JavaScript that calls the controller (I inherited this code but it works for other things).
function GetFile(url) {
//spin a wheel for friendly buffering time
var buffer = $('.MiddleRightDiv').spinBuffer();
$.ajax({
url: url,
type: "POST",
cache: false,
async: true,
data: {},
success: function (response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
},
complete: function (result) {
if (typeof $('.MiddleRightDiv').spinBuffer !== 'undefined' && $.isFunction($('.MiddleRightDiv').spinBuffer)) {
$('.MiddleRightDiv').spinBuffer("destroy");
}
}
});
Any input would be a great help. I have gone over other similar postings but non of them seems to address the core problem I am having.
Thanks,
dinsdale
jQuery.ajax cannot read bytestreams correctly (check SO for many topics about this), so we have to use old and good XMLHttpRequest. Here is your function refactored to work with blobs. Extened it with fallbacks for other browsers while saveAs(blob,filename) is the draft.
function GetFile(url) {
if (window.navigator.msSaveBlob) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.responseType = 'arraybuffer';
req.onload = function (e) {
if (req.response) {
var filename = 'archive.zip';
var disposition = req.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = req.getResponseHeader('Content-Type');
var blob = new Blob([req.response], { type: type ? type : 'application/octet' });
window.navigator.msSaveBlob(blob, filename);
} else {
throw 'Empty or invalid response';
}
}
req.send();
} else {
//fallback for browsers without blob saver
throw 'Not implemented';
}
}

why does this property return undefined?

I'm working on an AMR codec in Javascript and i cannot seem to get a file reference to be recognized by the decoder module. Here is a sample of my code:
reader.onload = (function (file) {
return function (e) {
var extension = file.name.split(".")[1];
if (extension === "amr") {
console.log("in try");
var stuff = e.target.result;
console.log(stuff.length);
var jigg = new AMR();
jigg.benchmark == 'true';
console.log(jigg); //jigg is defined, it's an instance of amr
// let's call some amr functions...
var dcoded = jigg.decode(stuff);
AMR.util.play(dcoded); //this throws an 'undefined' error, indicating that 'dcoded' is undefined.
} else if (extension == "wav") {
var data = e.target.result;
encodeWAV(data);
} else if (extension == "pcm" && isTypedArray) {
encodeRawPCM(new Int16Array(e.target.result));
}
};
})(f);
if ( !! isTypedArray) {
reader.readAsArraybuffer(f);
return;
}
// Read the file as a Binary String
reader.readAsBinaryString(f);
}
I have commented the line where the trouble occurs.
AMR.util.play(dcoded);

Categories