First time file not uploading in blueimp Jquery File Upload - jquery-file-upload

I am using Blueimp JqueryFileUpload, when i tried to upload my very first file its not uploading. But After i tried the same file or any file its working.
I can't figure out whats goes wrong for the very first upload.
While debugging i can found that the fileupload method not triggered for the first upload but followed consecutive uploads say second,third,.. its triggering
$('#fileUpload').fileupload({
url: 'home/upload',
dataType: 'json',
done: function (e, data) {
//do something
}
});

Are you generating the input file field after the page loads? I had the same issue because I forgot to initialize .fileupload() after the input field was appended.

Initialize .fileupload() method after form or form field is generated.
like
$('#fileupload'+rowNum).fileupload();
here $('#fileupload'+rowNum) is a dynamic form id.

Related

Intercept and edit multipart form-data POST request body in Browser

I've got a site that accepts file uploads which are sent as multipart/form-data within a POST request. To verify that the upload, which shows the filename afterwards, is secured against XSS I want to upload a file which contains HTML Tags in the filename.
This is actually harder than I expected. I can't create a file containing < on my filesystem (Windows). Also, I don't know a way to change the filename of the file input element inside the DOM before the upload (which is what I would do with normal/hidden inputs). So I thought about editing the POST body before it's uploaded, but I don't know how. Popular extensions (I recall Tamper Data, Tamper Dev) only let me change headers. I guess this is due to the plugin system of Chrome, which is the Browser I use.
So, what's the simplest way of manipulating the POST requests body? I could craft the entire request using cUrl, but I also need state, lots of additional parameters and session data etc. which gets quite complex... A simple way within the Browser would ne nice.
So, while this is not a perfect solution, it is at least a way to recreate and manipulate the form submit using FormData and fetch. It is not as generic as I'd like it to be, but it works in that case. Just use this code in the devtools to submit the form with the altered filename:
let formElement = document.querySelector('#idForm'); // get the form element
let oldForm = new FormData(formElement);
let newForm = new FormData;
// copy the FormData entry by entry
for (var pair of oldForm.entries()) {
console.log(pair[0]+': '+pair[1]);
if(typeof(pair[1]) == 'object' && pair[1].name) {
// alter the filename if it's a file
newForm.append(pair[0],pair[1],'yourNewFilename.txt');
} else {
newForm.append(pair[0],pair[1]);
}
}
// Log the new FormData
for (var pair of newForm.entries()) {
console.log(pair[0]+': ');
console.log(pair[1]);
}
// Submit it
fetch(formElement.action, {
method: formElement.method,
body: newForm
});
I'd still appreciate other approaches.

How to verify file type for multipart/form data upload in vertx?

I have a multipart/form with file upload in my Vert.x web application.
The issue I am running into is that I can only seem to validate the type of the uploaded file after having the request go through Vertx's BodyHandler.
Now I can validate the type after it went through, but the BodyHandler has already uploaded the file at this point in time. On a similair issue it was stated that you should check the content-type with your own handler before the BodyHandler, but this always returns an empty formAttributes.
I've tried creating my own handler:
public void handle(RoutingContext context) {
context.request().setExpectMultipart(true);
MultiMap attributes = context.request().formAttributes();
System.out.println(attributes);
context.next();
}
But attributes is always empty, so I can't verify the content-type of the file uploaded.
After it passes through the BodyHandler into my other handler it works fine:
MultiMap attributes = context.request().formAttributes();
Set<FileUpload> uploads = context.fileUploads();
for (FileUpload file : uploads
) {
System.out.println(file.contentType());
// This returns image/jpeg
}
context.response().end();
But as I stated above, the file is already uploaded when it has passed through the BodyHandler.
Here is the code for the handlers:
router.post("/api/someendpoint").handler(new FileTypeHandler());
router.post("/api/someendpoint").handler(BodyHandler.create()
.setUploadsDirectory("static/images")
.setBodyLimit(MB * 1));
router.post("/api/someendpoint").handler(new EndPointHandler());
How can I verify the type of a file being uploaded before it passes through the BodyHandler, so that I can reject any other file upload except an image?

Filepicker.io Javascript API Remove

Trying to use the remove function after the pick function and file is not being removed. (from here https://www.filepicker.com/documentation/file_ingestion/javascript_api/remove?v=v2)
selectFileMedium: function () {
filepicker.pick({
cropRatio: 24/13,
mimetype: 'image/*',
imageDim: [1440, 780]
}, function (Blob) {
InnerThis.uploadMediumImage(Blob.url, Blob.filename);
filepicker.remove(Blob);
});
}
Am I doing this correct?
Blob object return url property which is unificated url of uploaded file eg:
https://www.filepicker.io/api/file/AQgF2U68SNmJDpDXlOdg
However since v2 dialog version there is crop UI avaliable. If user crop file as a response it return the uploaded file url with appended Rest convert parameters:
https://www.filepicker.io/api/file/AQgF2U68SNmJDpDXlOdg/convert?crop=100,200,200,300
filepicker.remove dose not deal with it. Some temporary workaround would be to strip url from '/convert' part just before remove it. However it should be solved on library side.

Why when I upload of file-list the server-side code get an empty list?

First of all here's my jsFiddle, so you can see what I'm talking abuout.
I'm using blueimp/jQuery-File-Upload to manage files in the GUI of my asp-net application (server-side code is OK). If I manage the upload one-by-one I am able to upload that file successfully but as I try to submit the whole list the server does not recognize data and get only an empty list.
Here's the piece of code where my issue is:
//initialize fileupload()
$('#fileupload').fileupload({
//I call this function when I add file(s) to the list
add: function (e, data) {
//I do some more actions here
//Then I define this function when the submit button is clicked
$('#submitButton').click(function () {
//fix this?
data.submit();
});
}
)};
So, what am I doing wrong?
Your server should support multipart forms!
A solid handler for ASP.NET is Backload

Uploading BLOB/ArrayBuffer with Dropzone.js

Using SharePoint 2013 REST API, I'm successfully uploading files, such as .docx or .png's to a folder inside a document library using Dropzone.js. I have a function where I initialize my dropzone as follows:
myDropzone = new Dropzone("#dropzone");
myDropzone.on("complete", function (file) {
myDropzone.removeFile(file);
});
myDropzone.options.autoProcessQueue = false;
myDropzone.on("addedfile", function (file) {
$('.dz-message').hide();
myDropzone.options.url = String.format(
"{0}/{1}/_api/web/getfolderbyserverrelativeurl('{2}')/files" +
"/add(overwrite=true, url='{3}')",
_spPageContextInfo.siteAbsoluteUrl, _spPageContextInfo.webServerRelativeUrl, folder.d.ServerRelativeUrl, file.name);
});
myDropzone.options.previewTemplate = $('#preview-template').html();
myDropzone.on('sending', function (file, xhr, fd) {
xhr.setRequestHeader('X-RequestDigest', $('#__REQUESTDIGEST').val());
});
The problem I've encountered is that almost all the files (PDF being the only one not) are shown as corrupt files when the upload is done. This is most likely due to the fact SharePoint requires that the file being uploaded is sent as an ArrayBuffer. MSDN Source
Using a regular Ajax POST and the method above to convert the file to an arraybuffer, I've successfully uploaded content to the SharePoint document library, without them getting corrupt. Now, I would like to do the same but without having to omit the use of Dropzone.js, that adds a very nice touch to the interface of the functionality.
I've looked into modifying the uploadFiles()-method in dropzone.js, but that seems drastic. I've also tried to figure out whether or not I can use the accept option in options but that seems like a dead end.
The two most similar problems with solutions are the ones linked below, where the first seems to be applicable in my case, but at the same time looks less "clean" than I would want to use.
The second one is for uploading images with a Base64 encoding.
1 - Simulating XHR to get ArrayBuffer
2 - Upload image as Base64 with Dropzone.js
So my question in a few less words is, when a file is added, how do I intercept this, convert the data to an arraybuffer, and then POST it using Dropzone.js?
This is a late answer to my own question, but it is the solution we went for in the end.
We kept dropzone.js just for the nice interface and some help functions, but we decided to do the actual file upload using $.ajax().
We read the file as an array buffer using the HTML5 FileReader
var reader = new FileReader();
reader.onloadend = function(e) {
resolve(e.target.result);
};
reader.onerror = function(e) {
reject(e.target.error);
};
reader.readAsArrayBuffer(file);
and then pass it as the data argument in the ajax options.
I recently came across this exact issue and so did some investigation into the Dropzone library.
I managed to correct the upload process for SharePoint/Office 365 by monkey patching the Dropzone.prototype.submitRequest() method to modify it to use use my own getArrayBuffer method that returns an ArrayBuffer using the FileReader API before sending it via the Dropzone generated XMLHttpRequest.
This enables me to continue to use the features of Dropzone API.
Only tested on a single auto upload, so will need further investigation for multi file upload.
Monkey patch
Dropzone.prototype.submitRequest = function (xhr, formData, files) {
getArrayBuffer(files[0]).then(function (buffer) {
return xhr.send(buffer);
});
};
getArrayBuffer
function getArrayBuffer(file) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onloadend = function (e) {
resolve(e.target.result);
};
reader.onerror = function (e) {
reject(e.target.error);
};
reader.readAsArrayBuffer(file);
});
}
After the file is uploaded into SharePoint, I use the Dropzone 'success' event to update the file with metadata.