I have an HTML form that is used to upload a file to the server. This works correctly but now I am trying to expand the capability such that I select a tar file that consists of two binary files. Then untar the files and based on certain conditions either upload the first or the second file.
This is what I have done so far
use FileReader to read the tar file as ByteArray
use untar from js-untar to untar both file
I need help to figure out how to take the ByteArray for either files and add then to the FormData so that I can upload them.
Any help would be appreciated.
Here are snippets from my code
HTML Form
<form id="upform" enctype="multipart/form-data"
action="cgi-bin/upload2.cgi">
Firmware file: <input id='userfile' name="userfile" type="file" width=50 >
<input type
="submit" name="submitBtn" value="send file">
</form>
Untar code
function sendData() {
var formData = new FormData(form);
var action = form.getAttribute('action');
filesize = file.files[0].size;
var reader = new FileReader();
reader.onload = function() {
untar(reader.result).then(
function (extractedFiles) { // onSuccess
console.log('success');
formData.delete('userfile');
var reader2 = new FileReader();
reader2.onload = function() {
formData.append('userfile', reader2.result);
upload(formData);
}
var blob = new Blob([extractedFiles[0]], {type : 'multipart/form-data'});
reader2.readAsDataURL(blob);
// var f = URL.createObjectURL(blob);
},
function (err) {
console.log('Untar Error');
}
)
};
reader.readAsArrayBuffer(file.files[0]);
return;
}
function upload(formData) {
var action = form.getAttribute('action');
reqUpload.open('POST', action, true);
reqUpload.onreadystatechange = uploadState;
document.body.style.cursor = "wait";
var ld = document.getElementById("load");
ld.classList.add("loader");
reqUpload.send(formData);
document.getElementById('progress').style.display = "block";
progTimer = setInterval(ping, 10000);
uploadStarted = true;
return;
}
I'm using TinyMCE 5 with PHP 7.
Currently:
1. images_upload_handler (working)
Following the TinyMCE guide on Drag-in uploading images, and my own PHP upload AJAX handler, I got an image to upload successfully to my uploads directory:
This correctly uploads the file and keeps the correct name, using AJAX.
It uses a function for images_upload_handler, calling my AJAX handler.
2. file_picker_callback (incomplete)
Following the TinyMCE demo on uploading files, I got these two toolbar buttons (image, media) to show an upload button in their dialogs:
This works for image, not media.
It uses a function for file_picker_callback, uploading its own way.
3. The problem
I can't get the file_picker_callback from 2. to upload from media and I want it to use my own AJAX upload handler anyway, which I can't.
Using the image tool to upload, it will save the file after clicking "Save" in the dialog. But, when used in the media tool, it will not upload or insert anything at all.
It seems that this JavaScript demo provided by TinyMCE has a heavy interaction with the TinyMCE API itself. It has a system of caching and blobs to find the file that TinyMCE uploaded on its own. So pure AJAX-JS knowledge isn't sufficient to tell me how to tell TinyMCE to use my own AJAX upload PHP file. I'd rather just override TinyMCE's upload handler in file_picker_callback so I can use my own PHP upload script to be compatible with the rest of my app.
Goal:
I need a function for file_picker_callback (the file upload button) to use my own AJAX upload handler and preserve the name just as images_upload_handler succeeds in doing.
I am not worried about filename and mimetype validation; I plan to have PHP sanitize and filter later on.
This Question addresses another file uploader and the problem of TinyMCE 4 solutions not always working with TinyMCE 5.
This Question is about image description, and only for images; I want to upload any filetype.
I do not want any dependencies, not even jQuery. Vanilla JS only.
Current Code:
| upload.php :
$temp_file = $_FILES['file']['tmp_name'];
$file_path_dest = 'uploads/'.$_FILES['file']['name'];
move_uploaded_file($temp_file, $file_path_dest);
$json_file_is_here = json_encode(array('filepath' => $file_path_dest));
echo $json_file_is_here;
| tinyinit.js :
tinymce.init({
selector: 'textarea',
plugins: [ 'image media imagetools', ],
automatic_uploads: true,
images_reuse_filename: true,
images_upload_url: 'upload.php',
// From #1. Successful AJAX Upload
images_upload_handler: function(fileHere, success, fail) {
var ajax = new XMLHttpRequest();
ajax.withCredentials = false;
ajax.open('post', 'upload.php');
ajax.upload.onprogress = function (e) {
progress(e.loaded / e.total * 100);
};
ajax.onload = function() {
if (ajax.status == 200) {
if ( (!JSON.parse(ajax.responseText))
|| (typeof JSON.parse(ajax.responseText).filepath != 'string') ) {
fail('Invalid: <code>'+ajax.responseText+'</code>');
return;
}
success(JSON.parse(ajax.responseText).filepath);
} else {
fail('Upload error: <code>'+ajax.status+'</code>');
return;
}
};
var fileInfo = new FormData();
fileInfo.append('file', fileHere.blob(), fileHere.filename());
ajax.send(fileInfo);
},
file_browser_callback_types: 'file image media',
file_picker_types: 'file image media',
// From #2. Neither uploads from "media" nor uses my upload handler
file_picker_callback: function(cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(',')[1];
var blobInfo = blobCache.create(file.name, file, base64);
blobCache.add(blobInfo);
cb(blobInfo.blobUri(), { title: file.name });
};
reader.readAsDataURL(file);
};
input.click();
}
});
Editing #Aulia's Answer :
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
// FormData
var fd = new FormData();
var files = file;
fd.append('filetype',meta.filetype);
fd.append("file",files);
var filename = "";
// AJAX
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '/your-endpoint');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
alert('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
alert('Invalid JSON: ' + xhr.responseText);
return;
}
filename = json.location;
reader.onload = function(e) {
cb(filename);
};
reader.readAsDataURL(file);
};
xhr.send(fd);
return
};
input.click();
}
In the configuration you've provided, #2 doesn't have any logic to upload the data to your server. The code from Tiny's documentation you've copied is just for demo purposes and won't allow you to upload files to Tiny's servers.
You will need to setup the file_picker_callback callback to send data similar to images_upload_handler. On your server, you will need to send the URI and title in the response so the following line will be fulfilled:
cb(blobInfo.blobUri(), { title: file.name });
Hope it will helps mate, make your file_picker_callback looks like below codes
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
// FormData
var fd = new FormData();
var files = file;
fd.append('filetype',meta.filetype);
fd.append("file",files);
var filename = "";
// AJAX
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '/your-endpoint');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.location);
filename = json.location;
};
xhr.send(fd);
reader.onload = function(e) {
cb(filename);
};
reader.readAsDataURL(file);
return
};
input.click();
},
Need to determine if if pdf uploaded by user is password protected without using external libs.
So far got this POC.
Any one know cases when this might not work?
<input type='file' onchange='openFile(event)'><br>
<script>
var openFile = function (event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function (event) {
console.clear();
var contents = event.target.result;
if (contents.indexOf('/Encrypt') !== -1) {
console.log("Is encrypted");
} else {
console.log("Not encrypted");
}
console.log("File contents: " + contents);
};
reader.onerror = function (event) {
console.error("File could not be read! Code " +event.target.error.code);
};
reader.readAsText(input.files[0]);
};
</script>
You can use the below code to find whether the PDF is encrypted or not
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function () {
var files = new Blob([reader.result], {type: 'application/pdf'});
files.text().then(x=> {
console.log("isEncrypted", x.includes("Encrypt"))
console.log("isEncrypted", x.substring(x.lastIndexOf("<<"), x.lastIndexOf(">>")).includes("/Encrypt"));
console.log(file.name);
});
I am sending data via ajax to post in mysql. In this context how to inlude image file contents ?
If i use like :
var formData = document.getElementById("img_file");
alert(formData.files[0]);
, i get error . Note : img_file is the id of the file dom.
Any idea about this ?
You can use javascript FileReader for this purpose. Here is a sample code demonstration.
<html>
<body>
<input type="file" id="fileinput" />
<div id="ReadResult"></div>
<script type="text/javascript">
function readSingleFile(evt) {
//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function (e) {
var contents = e.target.result;
document.getElementById("ReadResult").innerHTML = contents;
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
</script>
</body>
</html>
Find more details here.
i think it may help you.
$('#image').change(function () {
$("#add").attr("disabled", true);
var img = this.files[0];
var reader = new FileReader;
reader.readAsDataURL(img);
reader.onload = function (e) {
var file = new Image;
file.src = e.target.result;
file.onload = function () {
$("#height").text(file.height);
$("#width").text(file.width);
$("#imageprev").attr("src", file.src);
$("#upld").removeAttr("disabled");
}
}
});
I am new to to the developing phonegap application. I need to choose the picture from the photolibrary after that need to store the path of the selected picture in localStorage, still this i did using destinationType as FILE_URI then i need to call another function which helps to converting the selected picture into base64 string by using File Reader's property readAsDataURL and upload that string to the server. The first part is working fine but that second part is not working please help me to solve this problem.
My HTML page is,
<button class="button" onclick="uploadImage();">From Photo Library</button>
<img style="display:none;width:60px;height:60px;" id="largeImage" src="" />
<button class="button" onclick="syncData();">Sync Data</button>
My Script.js is,
var pictureSource; // picture source
var destinationType;
document.addEventListener("deviceready",onDeviceReady,false);
function onDeviceReady() {
pictureSource=navigator.camera.PictureSourceType;
destinationType=navigator.camera.DestinationType;
}
var pictureSource = navigator.camera.PictureSourceType;
var destinationType = navigator.camera.DestinationType;
function uploadImage(){
alert('called upload pic');
//Using library
navigator.camera.getPicture(uploadPhoto, onFailcapturePhoto, { quality: 50,
destinationType: destinationType.FILE_URI, sourceType: pictureSource.PHOTOLIBRARY});
}
function onFailcapturePhoto(message) {
alert("Message = " + message);
}
function uploadPhoto(imageURI) {
if(!localStorage.imageArray) {
var imageArray = [];
imageArray.push(imageURI);
localStorage.setItem('imageArray',JSON.stringify(imageArray));
alert(JSON.stringify(imageArray));
} else {
var imagefile = JSON.parse(localStorage.imageArray);
imagefile.push(imageURI);
localStorage.setItem('imageArray',JSON.stringify(imagefile));
alert(JSON.stringify(imagefile));
}
var largeImage = document.getElementById('largeImage');
largeImage.style.display = 'block';
largeImage.src = imageURI; // here i can display the image
}
function syncData() {
var reader = new FileReader();
var selectedImageArray = [];
function readFile(index) {
alert('in read file'); // here i am getting alert
if( index >= JSON.parse(localStorage.imageArray).length ) return;
var file = JSON.parse(localStorage.imageArray)[index];
alert('file=='+file); // here i am getting path
reader.onloadend = function(e) {
// get file content
alert('in loadend');
selectedImageArray[index] = e.target.result;
alert('image data==:>'+selectedImageArray[index])
readFile(index+1);
}
if(file) {
alert('going to read'); // i got alert here, after this line i don't get anything
reader.readAsDataURL(file);
alert('reading finished');
} else {
alert('Your Browser does not support File Reader..');
}
}
readFile(0);
alert('before clear'+JSON.stringify(localStorage.imageArray));
localStorage.clear();
alert('after clear'+JSON.stringify(localStorage.imageArray));
}
Thanks & Regards,
Murali Selvaraj
By Following code i got answer for my question..
big thanks to this author..
my updated code is:
function uploadPhoto(imageURI) {
if (imageURI.substring(0,21)=="content://com.android") {
photo_split=imageURI.split("%3A");
imageURI="content://media/external/images/media/"+photo_split[1];
alert('new uri'+imageURI);
}
if(!localStorage.imageArray) {
var imageArray = [];
imageArray.push(imageURI);
localStorage.setItem('imageArray',JSON.stringify(imageArray));
alert(JSON.stringify(imageArray));
} else {
var imagefile = JSON.parse(localStorage.imageArray);
imagefile.push(imageURI);
localStorage.setItem('imageArray',JSON.stringify(imagefile));
alert(JSON.stringify(imagefile));
}
}
function syncData() {
var selectedImageArray = new Array();
function readFile(index) {
if( index >= JSON.parse(localStorage.imageArray).length ) {
if(selectedImageArray.length == 0) return;
$.ajax({
url : 'Here place your api', //your server url where u have to upload
type : 'POST',
dataType : 'JSON',
contentType : 'application/json',
data : JSON.stringify(selectedImageArray)
})
.done(function(res) {
alert('success='+res);
localStorage.clear();
})
.error(function(err) {
alert('error='+err);
});
} else {
var filePath = JSON.parse(localStorage.imageArray)[index];
window.resolveLocalFileSystemURI(filePath, function(entry) {
var reader = new FileReader();
reader.onloadend = function(evt) {
selectedImageArray.push(evt.target.result);
readFile(index+1);
}
reader.onerror = function(evt) {
alert('read error');
alert(JSON.stringify(evt));
}
entry.file(function(f) {
reader.readAsDataURL(f)
}, function(err) {
alert('error='+err);
});
});
}
}
readFile(0);
}