Valums FileUploader no response from server after upload - javascript

I am using Valums FileUploader and I am having trouble getting and reading a response after a file is uploaded. Basically I am trying to get a useful response to be used in onComplete, whether that be success or an error message.
I found another post here that said perhaps the server needs to be set to content-type plain/text. I checked that, and indeed that is the setting.
Anyway, been doing a lot of searching and finding various things to check, but nothing yet seems to solve my problem.
Here is some abbreviated code from the uploader:
var uploader = new qq.FileUploaderBasic({
button: document.getElementById('btnUpChange'),
action: templateURL+'/upload.php',
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'],
onSubmit: function(id, fileName) {
},
onComplete: function(id, fileName, responseJSON) {
var fileMsg = responseJSON;
console.log(fileMsg);
$('#filemsg').html('<span class="red" >'+fileMsg+'</span>');
}
});
And here is the text from the console after upload:
"[uploader] xhr - server response received"
"[uploader] responseText = File is too large"
[object Object]
I intentionally set the $sizeLimit small to throw an error just to try and get a message.
I took the php.php file included in the uploader zip, copied and renamed it, then added at the end this:
$allowedExtensions = array('jpg', 'jpeg', 'png', 'gif');
$sizeLimit = 4 * 1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
// Call handleUpload() with the name of the folder, relative to PHP's getcwd()
$result = $uploader->handleUpload('uploads/', $replaceOldFile = true);
if ($result['success'] !== true) {
echo $result['error'];
} else {
echo $result['success'];
}
If the upload is successful, I just get a 1 returned to the onComplete method. I tried to use responseJSON.responseText and all I got was "undefined".
Thank you for your help.

Found the solution to this...
First, on the php.php I put at the end this code:
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
Then, in the onComplete function the JSON response can be returned like this:
onComplete: function(id, fileName, responseJSON) {
var newFile = responseJSON.filename;
var theError = responseJSON.error;
}
where the key name from the response array created in the php.php can be anything you want and is returned as in the example like this: responseJSON.keyname

Related

Dropzonejs trigger error and cancel upload

i'm using Dropzonejs and what I would like to do is essentially simple. But I can't find any article about it.
So on sending the file we trigger an error on nasty .exe and .php files. The dropzonejs interface show an X and and error message. So that's correct. The problem is that it still gets thrown into the on success event, and gets uploaded.
uploader.on("sending", function (file, xhr, data) {
var aDeny = [ // deny file some extensions by default
'application/x-msdownload',
'text/php'
];
if($.inArray(file.type, aDeny) !== -1) {
this.defaultOptions.error(file, 'File not allowed: ' + file.name);
return false;
}
});
Evil.exe still appears in this success event and gets uploaded. The response only has a string of the file path and file.status is success.
uploader.on('success', function (file, response) {
getData({'dostuff'});
return file.previewElement.classList.add("dz-success");
});
So in my 'sending' event, how can I prevent the file from appearing in the success event?
UPDATE:
Thanks! This is what I needed in the end:
var aDeny = [ // deny file some extensions by default
'application/x-msdownload',
'text/php'
];
Dropzone.options.uploadWidget = {
// more config...
accept: function (file, done) {
if ($.inArray(file.type, aDeny) !== -1) {
done("This file is not accepted!");
}
else {
done();
}
}
}
I would first of all always check the file type on the server side to prevent any problems.
Then to filter file types with Dropzone you can use:
acceptedFiles option
The default implementation of accept checks the file's mime type or
extension against this list. This is a comma separated list of mime
types or file extensions.
Eg.: image/*,application/pdf,.psd
If the Dropzone is clickable this option will also be used as accept
parameter on the hidden file input as well.
Sample:
var myDropzone = new Dropzone("div#myId", {
url: "/file/post",
acceptedFiles: 'application/x-msdownload,text/php'
});
accept function
A function that gets a file and a done function as parameters.
If the done function is invoked without arguments, the file is
"accepted" and will be processed. If you pass an error message, the
file is rejected, and the error message will be displayed. This
function will not be called if the file is too big or doesn't match
the mime types.
Sample:
Dropzone.options.myAwesomeDropzone = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 2, // MB
accept: function(file, done) {
if (file.name == "justinbieber.jpg") {
done("This file is not accepted!");
}
else { done(); }
}
};

Response for FileUploader's uploadComplete-Event is undefined

I'm developing a SAPUI5 app and use the FileUploader control in my app to upload documents to a server. The uploading works and I also receive a response from the server (I can see this in the DevTools of Chrome).The problem is that the event-object inside the 'uploadComplete' event-handler always returns undefined for the response parameter.
Do you know why this is the case and how I can fix it?
Here is the initialization of the FileUploader:
var oFileUploader = new sap.ui.unified.FileUploader({
uploadUrl: "/fileupload",
name: "documentUploader",
uploadOnChange: false,
multiple: false,
width: "400px",
uploadComplete: this.onDocumentUploadComplete
});
And here is the 'uploadComplete' event-handler:
onDocumentUploadComplete: function(oEvent) {
var response = oEvent.getParameter("response");
console.log(response); // response = undefined
}
I still haven't figured out how to receive the server's response but I have found a workaround.After uploading the file I just send a request to the server and tell it to check whether the file exists.If it exists the server returns "true" and if it doesn't the server returns "false". Here's my code:
// eventhandler for the "uploadComplete"-event of the FileUploader-control
onDocumentUploadComplete: function(oEvent) {
var uploaderControl = oEvent.getSource();
var documentname = uploaderControl.getValue();
var fileURI = "/file/" + documentname + "?exists";
$.get(fileURI, function(data) {
if (data === "true") {
console.log("Successfully uploaded: " + documentname);
this.handleDocumentUploadSuccess(documentname);
} else {
console.log("Error when uploading document: " + documentname);
this.handleDocumentUploadError(documentname);
}
}.bind(this));
}
According to the documentation the parameter response is subject to some conditions.
Response message which comes from the server. On the server side this
response has to be put within the "body" tags of the response document
of the iFrame. It can consist of a return code and an optional
message. This does not work in cross-domain scenarios.
That means the response fom the server must be XML or HTML.

DropZone.js determine when successful upload

I am using Dropzone.js to upload an Excel file, of which it's contents is then imported to a table in my database.
I currently have methods in my c# which check the file being uploaded, to make sure it is valid (checks header row) and can be imported to the database.
The validation works fine, as does DropZone.js in theory. However, no matter if the file passes validation and is imported, or not, DropZone will always show the 'tick/check' mark - to notify the user that the action has completed successfully.
Here is my Dropzone:
Dropzone.options.forecastDropzone = {
init: function () {
thisDropzone = this;
this.on("success", function (file, Message) {
console.log(Message.Message)
toastr.info(Message.Message, {
timeOut: 0, tapToDismiss: true, preventDuplicates: true
});
});
},
};
HTML:
<form action="/Power/Upload" class="dropzone" id="forecastDropzone"></form>
And the 'Upload' method which is being called:
[HttpPost]
public ActionResult Upload()
{
string filename = "";
string path = "";
try
{
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
path = AppDomain.CurrentDomain.BaseDirectory + "Uploads/";
filename = Path.GetFileName(Request.Files[fileName].FileName);
Request.Files[fileName].SaveAs(Path.Combine(path, filename));
ValidateExcel(path, filename);
}
}
catch
{
isSavedSuccessfully = false;
}
return Json(isSavedSuccessfully == true ? new { Message = "Successfully Saved!" } : new { Message = "Error in saving file" });
}
So the Upload method is returning a JSON object. And I want DropZone to determine whether the save/import was successful, based on a value from the JSON. Is this possible?
Many thanks
Instead of trying to parse the JSON response and handle the error client side, I would make your server responsible for this.
Specifically: have your server return something other than a successful HTTP 200 response when an upload fails. DropZone will treat an upload as failed if it receives a 4xx or 5xx response from the server.

Struts2 Action Form Data Maximum Size for Image Upload using Base64

I have a Struts2 action that receives a string containing an image in Base64 and another string for the image name.
Everything works well for small sized images. But when I try to send a larger image, the Base64 and the image name strings are set to null in the action implementation.
In search for a solution I found that the default maximum size for the file upload is 2 MB. This limit can be increased with the following properties:
<constant name="struts.multipart.maxSize" value="104857600" />
<param name="maximumSize">52428800</param>
<param name="fileUpload.maximumSize">52428800</param>
However this is not working. Probably this implementation is not a file upload but a two string POST request.
Is there a way I can increase the size of the post request? Or the problem is something else?
public class GalleryAction extends BaseAction {
private String imageBase64;
private String imageName;
...
public final String uploadOperation() throws Exception {
if (this.imageBase64 == null || this.imageBase64.length() == 0
|| this.imageName == null || this.imageName.length() == 0) {
throw new Exception("Invalid argument");
}
byte[] decodedBytes = Base64Decoder.decode2bytes(this.imageBase64);
InputStream is = new ByteArrayInputStream(decodedBytes);
Graphics graphics = MGraphics.insertImageToDataBase(this.imageName, is);
// Issue server to sync image.
RestUtils.syncImage(graphics.getId());
JSONObject response = new JSONObject();
response.put("statusCode", "0");
jsonString = response.toString();
return JSON_RESPONSE;
}
...
}
EDIT:
I forgot to publish the code for the image upload.
Gallery.prototype.upload = function(base64, imageName) {
var galleryObject = this;
galleryObject.loadingCallback(true);
$.post(this.urlBase + "/upload", {
"imageBase64" : base64.match(/,(.*)$/)[1],
"imageName" : imageName
}, function(data) {
galleryObject.handlerErrorMessageCallback();
galleryObject.loadingCallback(false);
galleryObject.refreshImageGalleryCallback();
}, "json")
.fail(function() {
galleryObject.handlerErrorMessageCallback("error.upload.image");
galleryObject.loadingCallback(false);
});
}
The HTTP protocol specifications don't set a limit to the size of a POST message. However, your application server does it (mainly to prevent DDoS attacks).
Usually this threshold is 10 MegaBytes, and it is the one you are hitting. You should then be able to customize this setting according to your AS specs.
That said, this is not encouraged, and could lead to security vulnerabilities.
The best thing would be to:
use multipart/form-data over application/x-www-form-urlencoded;
use File instead of String since what you're uploading are files, and not strings.
I changed the upload method to Form data.
Gallery.prototype.upload = function(base64, imageName) {
var galleryObject = this;
galleryObject.loadingCallback(true);
var request = new FormData();
request.append("imageBase64", base64.match(/,(.*)$/)[1]);
request.append("imageName", imageName);
$.ajax({url:this.urlBase + "/upload",
data: request,
type: "POST",
processData: false,
contentType: false,
success: function(result)
{
galleryObject.handlerErrorMessageCallback();
galleryObject.loadingCallback(false);
galleryObject.refreshImageGalleryCallback();
}
}).fail(function() {
galleryObject.handlerErrorMessageCallback("error.upload.image");
galleryObject.loadingCallback(false);
});
}
Using this post method the following property on strus.xml must exists
<constant name="struts.multipart.maxSize" value="104857600" />

Publishing photo as multipart/form-data to Facebook using Javascript graph API v2.5

Facebook's Graph API (v2.5) User Photo Edge says that there are two separate ways of publishing photos to Facebook:
1: Attach the photo as multipart/form-data. The name of the object doesn't matter, but historically people have used source as the parameter name for the photo.How this works depends on the SDK you happen to be using to do the post.
2: Use a photo that is already on the internet by publishing using the url parameter:
FB.api(
"/me/photos",
"POST",
{
"url": "{image-url}"
},
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need to use the first method (multipart) as I have got the base64 image data from canvas.
This seems to be confusing as I don't find the documentation very informative. I understand that the urlData of image is to be encoded in some format in the multipart data along with other parameters. I fail to find any working sample code/proper explanation on how to do this using Javascript SDK & graph api v2.5; even after an exhaustive search on stackoverflow. I have seen a various partially answered/unanswered questions regarding this on stackoverflow...But I still fail to get it work.
Please help. Thanks !
Similar Questions
Facebook Javascript Form Data Photo Upload: requires upload file error
Javascript: Upload image from Canvas to FB via Graph API
Upload Base64 Image Facebook Graph API - Not clear if Javascript Api has been here
[Edit] - Code I have already tried.
var ctx = document.getElementById('canvas2');
urldata=ctx.toDataURL("image/png");
FB.api('/photos', 'POST', {
message: 'testing Graph API',
access_token: accessToken,
url: urldata,
no_story:true
}, function (response) {
if (!response || response.error) {
console.log('Error occured:' + response.error.message);
} else {
alert('Post ID: ' + response.id);
}
}
);
Response -"
Error occured:(#324) Missing or invalid image file "
I was not able to use the JS SDK with this, but it works with a simple AJAX request (with the Fetch API, axios or something else).
First, turn the Canvas Image into a Blob with the following function:
const dataURItoBlob = (dataURI) => {
let byteString = atob(dataURI.split(',')[1]);
let ab = new ArrayBuffer(byteString.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: 'image/jpeg'
});
}
After that, you can use the blog with FormData:
formData.append('source', blob);
Source: http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-from-canvas/

Categories