I am able to implement the image upload example found in the documentation of TinyMCE:
https://www.tinymce.com/docs/advanced/php-upload-handler/
My question is how can I show the user a specific error message when an error occurs? For example, if I upload an invalid file type, it only shows a generic 500 error message like this:
How can I show a more specific error message to the user like
"Invalid extension"?
Hi need to write your custom images_upload_handler.
In settings add this lines :
images_upload_handler : function handler(blobInfo, success, failure, progress) {
{
var valid_extensions = ['png','jpg']
var ext, extensions;
extensions = {
'image/jpeg': 'jpg',
'image/jpg': 'jpg',
'image/gif': 'gif',
'image/png': 'png'
};
ext = extensions[blobInfo.blob().type.toLowerCase()] || 'dat';
//add your extension test here.
if( valid_extensions.indexOf(ext) == -1){
failure("Invalid extension");
return;
}
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.open('POST', settings.url);
xhr.withCredentials = settings.credentials;
xhr.upload.onprogress = function(e) {
progress(e.loaded / e.total * 100);
};
xhr.onerror = function() {
failure("Image upload failed due to a XHR Transport error. Code: " + xhr.status);
};
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(pathJoin(settings.basePath, json.location));
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
}
}
Related
I use XMLHttpRequest to send POST data to nodejs (expressjs api). The size of file about 200mb. When I do, Chrome crashes, but the Firefox doesn't. Does Chrome have a limited file size?
And how can I upload the large file via JavaScript?
This is my code send xhr request:
// create http request API AI Engine
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'arraybuffer';
xhr.timeout = 3600000;
xhr.onload = function() {
// reponse measage
if (this.status === 200) {
var errorArea = document.getElementById('error-area');
errorArea.style.display = 'none';
zip.files = {};
// unzip File
zip.loadAsync(this.response)
.then(function(zip) {
// will be called, even if content is corrupted
for (const file in zip.files) {
if (zip.files.hasOwnProperty(file)) {
const fileObject = zip.files[file];
fileObject.async('arraybuffer').then(function(fileData) {
var fileSave = new Blob([new Uint8Array(
fileData)]);
// Save file
saveAs(fileSave, fileObject.name);
})
}
}
}, function(e) {
var errorArea = document.getElementById('error-area');
errorArea.style.display = 'block';
errorArea.innerHTML =
'<strong>Error</strong> Cant not unzip file return.';
});
// get response stream data
} else {
var errorArea = document.getElementById('error-area');
errorArea.style.display = 'block';
errorArea.innerHTML =
'<strong>Error</strong> Cant not analyze file: ' + this.statusText;
}
};
// Handle when have error with xhr, show message
xhr.onerror = function(err) {
var errorArea = document.getElementById('error-area');
errorArea.style.display = 'block';
errorArea.innerHTML =
'<strong>Error</strong> Cant not analyze file: ' + this.statusText;
};
// Handle when have timeout with xhr, show message
xhr.ontimeout = function() {
var errorArea = document.getElementById('error-area');
errorArea.style.display = 'block';
errorArea.innerHTML =
'<strong>Error</strong> Cant not analyze file: Request time out';
};
// Add custom header
xhr.setRequestHeader('Content-type', 'application/octet-stream');
xhr.setRequestHeader('file-name', Date.now().toString() + '.zip');
xhr.setRequestHeader('file-length', data.byteLength);
// Send arraybuffer to server
xhr.send(data);
});
I'm using Trix (https://github.com/basecamp/trix) as a text-editor in my app and allow for file uploads through there. I want to add a 5mb max file size to my uploads, but am a little lost at how to go about it. How would you implement it?
(function() {
var createStorageKey, host, uploadAttachment;
document.addEventListener("trix-attachment-add", function(event) {
var attachment;
attachment = event.attachment;
if (attachment.file) {
return uploadAttachment(attachment);
}
});
host = "https://my.cloudfront.net/";
uploadAttachment = function(attachment) {
var file, form, key, xhr;
file = attachment.file;
key = createStorageKey(file);
form = new FormData;
form.append("key", key);
form.append("Content-Type", file.type);
form.append("file", file);
xhr = new XMLHttpRequest;
xhr.open("POST", host, true);
xhr.upload.onprogress = function(event) {
var progress;
progress = event.loaded / event.total * 100;
return attachment.setUploadProgress(progress);
};
xhr.onload = function() {
var href, url;
if (xhr.status === 204) {
url = href = host + key;
return attachment.setAttributes({
url: url,
href: href
});
}
};
return xhr.send(form);
};
createStorageKey = function(file) {
var date, day, time;
date = new Date();
day = date.toISOString().slice(0, 10);
time = date.getTime();
return "tmp/" + day + "/" + time + "-" + file.name;
};
}).call(this);
You should do it client side AND server side. For the client side, just add one condition like so :
file = attachment.file;
if (file.size == 0) {
attachment.remove();
alert("The file you submitted looks empty.");
return;
} else if (file.size / (1024*2)) > 5) {
attachment.remove();
alert("Your file seems too big for uploading.");
return;
}
Also you can look at this Gist i wrote, showing a full implementation : https://gist.github.com/pmhoudry/a0dc6905872a41a316135d42a5537ddb
You should do it on server side and return an exception if the file size exceeds 5mb. You can also validate it on client-side through event.file, it has an "size" attribute, you can get the fize size from there.
if((event.file.size / (1024*2)) > 5) {
console.log('do your logic here');
}
Im following this guide to use aJax to upload an image, mainly so I can have a progress bar. But for some reason the PHP script doesn't seem to receive a file!
Here is my JavaScript:
function submitFile() {
var form = document.forms.namedItem("imageUpload");
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open("POST", "php/uploadImage.php", true);
xhr.onload = function(e) {
if (xhr.status == 200) {
console.log("uploaded!");
doc("imageResponse").innerHTML = xhr.responseText;
} else {
console.log("error!");
doc("imageResponse").innerHTML += "Error " + xhr.status + " occurred when trying to upload your file.<br \/>";
}
};
//Progress
/*
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var currentPercentage = Math.round(e.loaded / e.total * 100);
document.getElementById("imageUpload").innerHTML = "UPLOAD IMAGE " + currentPercentage + "%";
document.getElementById("imageUpload").style.backgroundSize = currentPercentage + "% 100%";
}
};
*/
//Send data
xhr.send(formData);
}
And here is my PHP file which receives the file:
<?php
session_start();
print_r($_FILES);
?>
Currently that PHP file is returning an empty Array... it should have my file!
Array ( )
I managed to fix my code, here is the working version for anyone with the same problem. I decided to make a new form using JavaScript and append the file field value to this new form.
I did this mainly for my situation.
function submitFile(file,buttonId) {
//Generate a new form
var f = document.createElement("form");
f.setAttribute("method", "POST");
f.setAttribute("enctype", "multipart/form-data");
//Create FormData Object
var formData = new FormData(f);
//Append file
formData.append("image", file.files[0], "image.jpg");
var xhr = new XMLHttpRequest();
xhr.open("POST", "php/uploadImage.php", true);
xhr.onload = function(e) {
if (xhr.status == 200) {
document.getElementById(buttonId).innerHTML = "UPLOAD COMPLETE";
//console.log("uploaded!");
} else {
//console.log("error!");
alert("Error " + xhr.status + " occurred when trying to upload your file");
}
};
//Progress
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var currentPercentage = Math.round(e.loaded / e.total * 100)-1;
document.getElementById(buttonId).innerHTML = "UPLOAD IMAGE " + currentPercentage + "%";
document.getElementById(buttonId).style.backgroundSize = (currentPercentage+1) + "% 100%";
if (currentPercentage==99) {
document.getElementById(buttonId).innerHTML = "Processing image";
}
}
};
//Send data
xhr.send(formData);
}
I have written the following code for download file from Google drive using JavaScript but I am not able to open file after completion of download its giving error like file format does not match my code as below,
function createPicker() {
var picker = new FilePicker({
apiKey: 'myapikey',
clientId: 'myclientID',
buttonEl: document.getElementById('ancggdgdgdd'),
onSelect: function (file) {
downloadFile(file);
}
});
}
and to read the content of file code as:
function downloadFile(doc) {
var myToken = gapi.auth.getToken();
var contentType = "text/plain;charset=utf-8";
var rawFile = new XMLHttpRequest();
rawFile.open("GET", doc.downloadUrl, false);
rawFile.setRequestHeader('Content-type', contentType)
rawFile.setRequestHeader('Authorization', 'Bearer ' + myToken.access_token);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
sendFile(rawFile.responseText);//here I am sending httpcontext
}
}
}
//rawFile.responseType = "arraybuffer";
rawFile.send(null);
}
Try this function for downloading the files:
/**
* Download a file's content.
*
* #param {File} file Drive File instance.
* #param {Function} callback Function to call when the request is complete.
*/
function downloadFile(file, callback) {
if (file.downloadUrl) {
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open('GET', file.downloadUrl);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function() {
callback(xhr.responseText);
};
xhr.onerror = function() {
callback(null);
};
xhr.send();
} else {
callback(null);
}
}
You can find more information in the following link: https://developers.google.com/drive/web/manage-downloads
here is the upload logic in js
var upload = function(){
if(_file.files.length === 0){
return;
}
var data = new FormData();
data.append('SelectedFile', _file.files[0]);
var request = new XMLHttpRequest();
request.onreadystatechange = function(){
if(request.readyState == 4){
try {
var resp = JSON.parse(request.response);
} catch (e){
var resp = {
status: 'error',
data: 'Unknown error occurred: [' + request.responseText + ']'
};
}
console.log(resp.status + ': ' + resp.data);
}
};
request.upload.addEventListener('progress', function(e){
_progress.style.width = Math.ceil(e.loaded/e.total) * 100 + '%';
}, false);
request.open('POST', 'upload.php');
request.send(data);
}
I run the function every time user selected something, but I only got the first file if user selected multiple files.
That's because you're only adding the first file to your data object:
data.append('SelectedFile', _file.files[0]);
You need to add all your files in the _file.files collection
Something like:
for(var i = 0 ; i < _file.files.length; i++ ) {
data.append('SelectedFile'+i, _file.files[i]);
}
var data = new FormData();
data.append('SelectedFile', _file.files[0]);
Instead of this code, try something like this:
var data = new FormData();
for (var i in _file.files) data.append('SelectedFile'+i, _file.files[i]);