New to javascript, having trouble figuring this out, help!
I am trying to use the Javascript FileReader API to read files to upload to a server. So far, it works great for text files.
When I try to upload binary files, such as image/.doc, the files seem to be corrupted, and do not open.
Using dojo on the client side, and java on the server side, with dwr to handle remote method calls. Code :
Using a html file input, so a user can select multiple files to upload at once :
<input type="file" id="fileInput" multiple>
And the javascript code which reads the file content:
uploadFiles: function(eve) {
var fileContent = null;
for(var i = 0; i < this.filesToBeUploaded.length; i++){
var reader = new FileReader();
reader.onload = (function(fileToBeUploaded) {
return function(e) {
fileContent = e.target.result;
// fileContent object contains the content of the read file
};
})(this.filesToBeUploaded[i]);
reader.readAsBinaryString(this.filesToBeUploaded[i]);
}
}
The fileContent object will be sent as a parameter to a java method, which will write the file.
public boolean uploadFile(String fileName, String fileContent) {
try {
File file = new File("/home/user/files/" + fileName);
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(fileContent.getBytes());
outputStream.close();
} catch (FileNotFoundException ex) {
logger.error("Error uploading files: ", ex);
return false;
} catch (IOException ioe) {
logger.error("Error uploading files: ", ioe);
return false;
}
return true;
}
I have read some answers suggesting the use of xhr and servlets to achieve this.
Is there a way to use FileReader, so that it can read files of any type (text, image, excel etc.) ?
I have tried using reader.readAsBinaryString()
and reader.readAsDataUrl()
(Decoded the base64 fileContent before writing to a file), but they did not seem to work.
PS :
1. Also tried reader.readAsArrayBuffer()
, the resultant ArrayBuffer
object shows some byteLength
, but no content, and when this is passed to the server, all I see is {}
.
- This bit of code is intended to work on only newer versions of browsers..
New to javascript, having trouble figuring this out, help!
I am trying to use the Javascript FileReader API to read files to upload to a server. So far, it works great for text files.
When I try to upload binary files, such as image/.doc, the files seem to be corrupted, and do not open.
Using dojo on the client side, and java on the server side, with dwr to handle remote method calls. Code :
Using a html file input, so a user can select multiple files to upload at once :
<input type="file" id="fileInput" multiple>
And the javascript code which reads the file content:
uploadFiles: function(eve) {
var fileContent = null;
for(var i = 0; i < this.filesToBeUploaded.length; i++){
var reader = new FileReader();
reader.onload = (function(fileToBeUploaded) {
return function(e) {
fileContent = e.target.result;
// fileContent object contains the content of the read file
};
})(this.filesToBeUploaded[i]);
reader.readAsBinaryString(this.filesToBeUploaded[i]);
}
}
The fileContent object will be sent as a parameter to a java method, which will write the file.
public boolean uploadFile(String fileName, String fileContent) {
try {
File file = new File("/home/user/files/" + fileName);
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(fileContent.getBytes());
outputStream.close();
} catch (FileNotFoundException ex) {
logger.error("Error uploading files: ", ex);
return false;
} catch (IOException ioe) {
logger.error("Error uploading files: ", ioe);
return false;
}
return true;
}
I have read some answers suggesting the use of xhr and servlets to achieve this.
Is there a way to use FileReader, so that it can read files of any type (text, image, excel etc.) ?
I have tried using reader.readAsBinaryString()
and reader.readAsDataUrl()
(Decoded the base64 fileContent before writing to a file), but they did not seem to work.
PS :
1. Also tried reader.readAsArrayBuffer()
, the resultant ArrayBuffer
object shows some byteLength
, but no content, and when this is passed to the server, all I see is {}
.
- This bit of code is intended to work on only newer versions of browsers..
- Sorry, I think I accidentally overwrote someone else's edits – bub Commented Jan 9, 2015 at 6:58
- 2 Have you tried using typed array views to read from the array buffer? Since you are using java on the server, and need to write the bytes to a file, you should find 'Int8Array' interesting. Check this out - developer.mozilla/en-US/docs/Web/JavaScript/Typed_arrays – N.M Commented Jan 9, 2015 at 8:02
- 2 Also, looks like FileReader.readAsBinaryString is deprecated as per the 12 July 2012 Working Draft from the W3C. Source - developer.mozilla/en-US/docs/Web/API/… – N.M Commented Jan 9, 2015 at 8:11
3 Answers
Reset to default 2Thanks N.M! So, it looks like ArrayBuffer objects cannot be used directly, and a DataView must be created in order to use them. Below is what worked -
uploadFiles: function(eve) {
var fileContent = null;
for(var i = 0; i < this.filesToBeUploaded.length; i++){
var reader = new FileReader();
reader.onload = (function(fileToBeUploaded) {
return function(e) {
fileContent = e.target.result;
var int8View = new Int8Array(fileContent);
// now int8View object has the content of the read file!
};
})(this.filesToBeUploaded[i]);
reader.readAsArrayBuffer(this.filesToBeUploaded[i]);
}
}
Refer N.M 's ments to the question for links to the relevant pages.
https://developer.mozilla/en-US/docs/Web/JavaScript/Typed_arrays
example
<html>
<head>
<link rel="stylesheet" href="http://code.jquery./ui/1.11.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery./jquery-1.10.2.js"></script>
<script src="http://code.jquery./ui/1.11.3/jquery-ui.js"></script>
</head>
<body>
<script>
function PreviewImage() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
oFReader.onload = function (oFREvent) {
var sizef = document.getElementById('uploadImage').files[0].size;
document.getElementById("uploadPreview").src = oFREvent.target.result;
document.getElementById("uploadImageValue").value = oFREvent.target.result;
};
};
jQuery(document).ready(function(){
$('#viewSource').click(function ()
{
var imgUrl = $('#uploadImageValue').val();
alert(imgUrl);
//here ajax
});
});
</script>
<div>
<input type="hidden" id="uploadImageValue" name="uploadImageValue" value="" />
<img id="uploadPreview" style="width: 150px; height: 150px;" /><br />
<input id="uploadImage" style="width:120px" type="file" size="10" accept="image/jpeg,image/gif, image/png" name="myPhoto" onchange="PreviewImage();" />
</div>
<a href="#" id="viewSource">Source file</a>
</body>
</html>
Rather than messing with a FileReader you can just upload the File object directly as it is already an instance of Blob and is in binary format. The FileReader is to change that already binary representation into something useful for the frontend like text or a data URL or an array buffer that can then be manipulated, not turn what is already binary into binary. In other words there is no point in reading it or using the FileReader API at all if you're just going to upload the binary content. Bonus tip: use multipart/form-data.