Limitations for controlling files with JavaScript - javascript

Please excuse me for not being good at English because I do not live in an English-speaking country.
I am student, and I want to make code for file encryption and download that file with jquery(in client side).
I solved it, but I have some problems.
When I upload file for encrypting file that has big size,
my site is crashed.
(My code will be applied to a simple homepage.)
When I run that process in firefox or icedragon browser, I can see error that 'allocation size overflow'.
Can you tell me why that problem happened?
The code I wrote is below and the reference address is here.
$(function(){
var body = $('body'),
stage = $('#stage'),
back = $('a.back');
/* Step 1 */
$('#step1 .encrypt').click(function(){
body.attr('class', 'encrypt');
// Go to step 2
step(2);
});
$('#step1 .decrypt').click(function(){
body.attr('class', 'decrypt');
step(2);
});
/* Step 2 */
$('#step2 .button').click(function(){
// Trigger the file browser dialog
$(this).parent().find('input').click();
});
// Set up events for the file inputs
var file = null;
$('#step2').on('change', '#encrypt-input', function(e){
// Has a file been selected?
if(e.target.files.length!=1){
alert('Please select a file to encrypt!');
return false;
}
file = e.target.files[0];
/*if(file.size > 1024*1024*50){
alert('Please choose files smaller than 50mb, otherwise you may crash your browser. \nThis WARNING is for you.');
return;
}*/
step(3);
});
$('#step2').on('change', '#decrypt-input', function(e){
if(e.target.files.length!=1){
alert('Please select a file to decrypt!');
return false;
}
file = e.target.files[0];
step(3);
});
/* Step 3 */
$('a.button.process').click(function(){
var input = $(this).parent().find('input[type=password]'),
a = $('#step4 a.download'),
password = input.val();
input.val('');
if(password.length<5){
alert('Please choose a longer password!');
return;
}
// The HTML5 FileReader object will allow us to read the
// contents of the selected file.
var reader = new FileReader();
if(body.hasClass('encrypt')){
// Encrypt the file!
reader.onload = function(e){
// Use the CryptoJS library and the AES cypher to encrypt the
// contents of the file, held in e.target.result, with the password
var encrypted = CryptoJS.AES.encrypt(e.target.result, password);
var encryptedFileArray = [encrypted];
var blob = 'Blob Data';
var fileName = file.name + '.encrypted';
if(window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
var blobEncrypted = new Blob(encryptedFileArray, { type: 'application/octet-stream' });
var blobUrl = URL.createObjectURL(blobEncrypted);
$(a).attr({
'download': file.name + '.encrypted',
'href': blobUrl
});
}
// The download attribute will cause the contents of the href
// attribute to be downloaded when clicked. The download attribute
// also holds the name of the file that is offered for download.
step(4);
};
// This will encode the contents of the file into a data-uri.
// It will trigger the onload handler above, with the result
reader.readAsDataURL(file);
}
else {
// Decrypt it!
reader.onload = function(e){
var decrypted = CryptoJS.AES.decrypt(e.target.result, password).toString(CryptoJS.enc.Latin1);
if(!/^data:/.test(decrypted)){
alert("Invalid pass phrase or file! Please try again.");
return false;
}
var url = decrypted;
var userAgent = navigator.userAgent;
var filename = file.name.replace('.encrypted','');
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function () {
$(a).attr({
'download': filename,
'href': window.URL.createObjectURL(xhr.response) // xhr.response is a blob
});
};
xhr.open('GET', url);
xhr.send();
step(4);
};
reader.readAsText(file);
}
});
/* The back button */
back.click(function(){
// Reinitialize the hidden file inputs,
// so that they don't hold the selection
// from last time
$('#step2 input[type=file]').replaceWith(function(){
return $(this).clone();
});
step(1);
});
// Helper function that moves the viewport to the correct step div
function step(i){
if(i == 1){
back.fadeOut();
}
else{
back.fadeIn();
}
// Move the #stage div. Changing the top property will trigger
// a css transition on the element. i-1 because we want the
// steps to start from 1:
stage.css('top',(-(i-1)*100)+'%');
}
});

xhr.open('GET', url);
you are using GET method. maybe is better using POST instead.
what is your server side language? is it PHP?
if that is PHP, should be better check the file upload size in "php.ini" file.

Related

Converting data:image base64 to blob in this code

I'd like to change the URLs from data:image base64 to blob. This is the original code that produces the base64 urls:
<script>
$(window).load(function(){
function readURL() {
var $input = $(this);
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', e.target.result).show();
$newinput.after('<div class="delbtn delete_upload" title="Remove"><span class="bbb-icon bbb-i-remove2"></span></div>');
$("form").on('click', '.delbtn', function (e) {
reset($(this));
$("form").find('#rright-<?php echo $i;?>').hide();
});
}
reader.readAsDataURL(this.files[0]);
}
}
$(".file").change(readURL);
function reset(elm, prserveFileName) {
if (elm && elm.length > 0) {
var $input = elm;
$input.prev('.portimg').attr('src', '').hide();
if (!prserveFileName) {
$($input).parent().parent().parent().find('input.file ').val("");
//input.fileUpload and input#uploadre both need to empty values for particular div
}
elm.remove();
}
}
});
</script>
What I want is to call Object.createObjectURL(this.files[0]) to get the object URL, and use that as the src of your img; (just don't even bother with the FileReader).
Something like this?
function readURL() {
var file = this.files[0]
var reader = new FileReader();
var base64string = getBase64(file);
reader.onload = function () {
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', e.target.result).show();
$newinput.after('<div class="delbtn delete_upload" title="Remove"><span class="bbb-icon bbb-i-remove2"></span></div>');
var blob = dataURItoBlob(base64string);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
I'm not sure if this will work and due to the vagaries of Stack Snippets, can't demonstrate its viability here on Stack Overflow, but theoretically, you should be able to use URL.createObjectURL to create the appropriate URL for your image, without going through the whole base 64 rigmarole.
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
$newinput.attr('src', URL.createObjectURL(this.files[0]));
// if the above doesn't work, you could try to create a new Blob
var fileBlob = new Blob(this.files[0], { type: "image/png" })
// Substitute "image/png" with whatever image type it is
$newinput.attr('src', URL.createObjectURL(fileBlob));
That should render the appropriate URL for the image's source.
Note that it is best practice to revoke the object URL when you are done with it. I'm not sure that's necessary in this case, since presumably you want to show the image until the page is closed. However, if the user can upload a new image, do something like:
if ($newinput.attr('src').indexOf('blob') > -1) {
URL.revokeObjectURL($newinput.attr('src'));
}
Add that before setting the new source and you shouldn't need to worry about memory leaks (from this use of createObjectURL anyway...).
For more information on Blob URLs, see this answer by a now-anonymous user to What is a blob URL and why it is used?

How to read from text file and show it as a dropdown (select) in html

I have a text file stored in my local which contains the list of usernames that i want to show as a drop down in html page. I need to know how to go about doing this also any piece of code or push in the right direction would be appreciated? P.S I am very new to coding !!
I have already tried loading text files to display as html using the below code
var openFile = function(event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var text = reader.result;
var node = document.getElementById('output');
node.innerText = text;
console.log(reader.result.substring(0, 200));
};
reader.readAsText(input.files[0]);
};
But this does not serve my purpose.
I would like a dropdown the options of which are populated from a text file.
You didn't provide the text file structure. So I don't know how is it. But according to your information, the simplest solution is to use,
HttpRequest
You can read about that here also.
function readFile(fileName)
{
var node = document.getElementById('output');
var xhttp = new XMLHttpRequest();
xhttp.open("GET", fileName, true);
xhttp.onreadystatechange = function ()
{
if(xhttp.readyState === 4)
{
if(xhttp.status === 200 || xhttp.status == 0)
{
var text = xhttp.responseText;
node.innerText = text;
}
}
}
xhttp.send();
}
And specify file:// in your filename when using an absolute path,
readFile("file:///Drive/and/your/path/to/file.ext");
This is to give you an idea. Hope this helps you.

How can I store a blob in a form and send it to the server when the clicks on submit without Ajax?

This is my function:
FileCropped.prototype.change = function () {
var obj = $(this).data("plugin.file-cropped");
var files = obj.$element[0].files;
var file;
var URL = window.URL || window.webkitURL;
var blobURL;
if (files && files.length) {
file = files[0];
console.log("I have files");
if (/^image\/\w+$/.test(file.type)) {
blobURL = URL.createObjectURL(file);
obj.$element.val('');
obj.$hidden[0].value = blobURL;
//URL.revokeObjectURL(blobURL);
} else {
window.alert('Please choose an image file.');
}
} else
{
console.log("No files?");
}
}
I am trying right now to attach the blob to an existing form input but it does not work. With the chrome debugger I see the method works fine and follow the expected path, but at the time of submit the server gets nothing.
Any hint?
Edit: of course the function has no value right now. I could just use the normal file input. The goal is to be able to manipulate the blob before attaching it to the form.
You can use FileReader to read the file as data URL
var fileReader = new FileReader();
fileReader.addEventListener('load', function () {
blobURL = fileReader.result;
obj.$hidden[0].value = blobURL;
});
fileReader.readAsDataURL(file);

How write Javascript for loading/writing contet from text-field from/to disk

how can I with a input text field with a button, let the user pick a .txt file from harddrive and also give the option of storing content from the text field onto harddrive, when using Chrome.
How can I do that with pure Javascript?
Kindest regards
/Lasse
Try using input type="file" with accepts MIME type set to "text/plain", textarea , a element , download attribute , FileReader , data: protocol , encodeURIComponent
var input = document.querySelector("input");
var text = document.querySelector("textarea");
var button = document.querySelector("button");
var name;
input.onchange = function() {
name = this.files[0].name;
var reader = new FileReader();
reader.onload = function() {
text.value = this.result
}
reader.readAsText(this.files[0])
}
button.onclick = function() {
var a = document.createElement("a");
// `"data:text/plain," + text.value` : new file
a.href = "data:text/plain;charset=utf-8," + encodeURIComponent(text.value);
a.download = name || "file-" + new Date().getTime();
document.body.appendChild(a);
// creates `"Save file"` dialog
a.click();
document.body.removeChild(a)
}
<input type="file" accepts="text/plain"/><br>
<textarea width="300px" height="200px">
</textarea><br>
<button>save</button>
A full answer to your question would be very lengthy, so briefly:
Use a form with an input that is type file that allows the user to input a file:
<form>Select file: <input type="file" id="loadfile"/></form>
Using javascript, react to the value being set by listening to either the submit event, the click event, or the change event. The example here looks at the change event.
var input = document.getElementById('loadfile');
input.onchange = function handleInputFileChanged(event) {
var files = event.target.files;
if(!files || !files.length) {
return;
}
importFiles(files);
};
function importFiles(files) {
// Read in the contents of the files as text and process them here
var numFiles = files.length;
var filesProcessed = 0;
for(var i = 0; i < numFiles; i++) {
processFile(files[i]);
}
function processFile(file) {
var reader = new FileReader();
reader.onload = function() {
filesProcessed++;
// do something with the file text, here i am just printing
// it to the browser console
var contentString = reader.result;
console.log('File text: %s', contentString);
if(filesProcessed === numFiles) allFilesRead();
};
reader.onerror = function() {
filesProcessed++;
if(filesProcessed === numFiles) allFilesRead();
};
reader.readAsText(file);
}
function allFilesRead() {
// do something now that all files have been read
}
}
To save to a file, this can be done simply by providing the user a prompt. For example:
<form><button id="savebutton" value="Save"></form>
In script, listen for the button click event, and then initiate a download:
var button = document.getElementById('savebutton');
button.onclick = function(event) {
var content = getContentToSaveAsString();
// to automatically start a download, we are going to create a
// hidden anchor element, then pseudo-click it
// Create the anchor and sets its href to a data uri
var anchor = document.createElement('a');
var blob = new Blob([content], {type: 'text/plain'});
var objectURL = URL.createObjectURL(blob);
anchor.href = objectURL;
anchor.setAttribute('download', 'defaultfilenamegoeshere.txt');
// attach the hidden anchor to the page
anchor.style.display = 'none';
document.body.appendChild(anchor);
// this starts the download, the user will get a prompt of where to
// save or if in chrome it just starts downloading to download
// folder, just as if they had right clicked on an anchor in
// the page and selected Save Target As
anchor.click();
// remove our temporary anchor element, cleaning up after ourselves
URL.revokeObjectURL(objectURL);
anchor.remove();
};
function getContentToSaveAsString() {
// Create and return a string here that will be saved to a
// text file when the user clicks the save button
return 'string of stuff';
}

How to check type of uploaded image through FileReader?

There is the following code which makes preview before uploading on the server:
$(function(){
var preview = $(".preview");
$("#menu_image").change(function(event){
var input = $(event.currentTarget);
var file = input[0].files[0];
var reader = new FileReader();
reader.onload = function(e){
var img = new Image;
img.onload = function() {
if ((img.with != 160) || (img.height != 160)) {
return;
}
preview.attr("src", img.src);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
});
});
But this code doesn't check file's type. How can I do it? Thanks in advance.
You don't need to load the FileReader to know file type.
Using your code:
var file = input[0].files[0];
is as easy as checking the file.type property.
You can check if the file is an image:
if (file.type.match('image.*')) {
console.log("is an image");
}
And which type of image is:
if (file.type.match('image.*')) {
console.log("is an image");
console.log("Show type of image: ", file.type.split("/")[1]);
}
Note that file.type.split("/")[1] should be an "image"
You can do something similar to check the file extension:
var extension = file.name.substring(file.name.lastIndexOf('.'));
// Only process image files.
var validFileType = ".jpg , .png , .bmp";
if (validFileType.toLowerCase().indexOf(extension) < 0) {
alert("please select valid file type. The supported file types are .jpg , .png , .bmp");
return false;
}
Try using the extension selector like this:
if($('img[src $= "jpg"]')) // if extension is jpg then dosomething
dosomething;

Categories

Resources