Jquery File Upload always fails with File Upload Aborted - javascript

I'm trying to get Blueimp's Jquery File Upload plugin working on my website, but for the life of me can't get it to upload files. I've been working on this all day and am stuck. It will upload the file and submit it to the UploadHandler class, but when it's trying to complete the handle_file_upload function it gets to:
file_put_contents(
$file_path,
fopen('php://input', 'r'),
$append_file ? FILE_APPEND : 0
);
but that always returns 0. I cannot figure out why the file won't upload. The full response I get back is:
{"files":[
{"name":"1397489968-32",
"size":0,
"type":"multipart\/form-data; boundary=----WebKitFormBoundaryrmi4L2ouOmB4UTVm",
"error":"File upload aborted",
"deleteUrl":"http:\/\/onceridden.demomycms.co.uk\/eshop\/library\/ajax\/?file=1397489968-32",
"deleteType":"DELETE"}
]}
ajax.file-upload.php only instantiates UploadHandler, nothing else.
If you'd like to see the full code you for UploadHandler you can download it from github, it's too big for me to post on here.
Can someone please tell me why the files won't upload? Yes I've done the basics such as checking the folder is CHMOD 777. I've tried this with various files of different types (they must be images to work, limited to jpg, png or gif) and sizes; all produce the same result.
As requested this is the JS file:
$(function () {
'use strict';
// Change this to the location of your server-side upload handler:
var url = '/eshop/library/ajax/ajax.file-upload.php',
uploadButton = $('<button/>')
.addClass('btn btn-primary')
.prop('disabled', true)
.text('Processing...')
.on('click', function () {
var $this = $(this),
data = $this.data();
$this
.off('click')
.text('Abort')
.on('click', function () {
$this.remove();
data.abort();
});
data.submit().always(function () {
$this.remove();
});
});
$('#register-photo').fileupload({
url: url,
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
maxFileSize: 5000000, // 5 MB
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
previewMaxWidth: 100,
previewMaxHeight: 100,
previewCrop: true
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#register-files');
$.each(data.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.preview) {
node
.prepend('<br>')
.prepend(file.preview);
}
if (file.error) {
node
.append('<br>')
.append($('<span class="text-danger"/>').text(file.error));
}
if (index + 1 === data.files.length) {
data.context.find('button')
.text('Upload')
.prop('disabled', !!data.files.error);
}
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#register-progress .progress-bar').css(
'width',
progress + '%'
);
}).on('fileuploaddone', function (e, data) {
$.each(data.result.files, function (index, file) {
if (file.url) {
var link = $('<a>')
.attr('target', '_blank')
.prop('href', file.url);
$(data.context.children()[index])
.wrap(link);
} else if (file.error) {
var error = $('<span class="text-danger"/>').text(file.error);
$(data.context.children()[index])
.append('<br>')
.append(error);
}
});
}).on('fileuploadfail', function (e, data) {
$.each(data.files, function (index, file) {
var error = $('<span class="text-danger"/>').text('File upload failed.');
$(data.context.children()[index])
.append('<br>')
.append(error);
});
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
It's pretty much the default file you get with the plugin with just the ID's changed to match my form.
Update
After much playing around and testing I have found out that the problem occurs when you change the name of the input from files to anything else. Why I have no idea. This is obviously an issue if you want to have it running on more than one input on a page...
I created a very simple version of the interface myself, and that does allow me to change the file name, so it must be something to do with the example they use. I would like to be able to use preview images and the such (something I couldn't figure out in my simple test) so I need to solve this issue.

This is in case anyone else ever gets stuck on this problem as well. The issue is caused by the paramName option, which if not set takes it's value from the input name. It's not set by default, so when changing the input name I was also changing paramName, meaning it no longer matched the variable coming back from the UploadHandler class.
The solution is to add paramName: 'files[]' as an option.

I was facing same issue(action aborted) and have different answer.
The folder/directory where I was uploading file did not have permission to upload file.
on Linux server you can run following command
chmod 777 files
When I gave permission to this directory, I did not get this error, and could upload file successfully.

I am running a centOS 6.9. chmod 0755 /server/php/files (rather than 777) and I changed the ownership (chown) over to apache. Ta-Da!

Related

Dropzone Js max File upload not work properly

Notes : i tired all questions & answer related this topic.
I use Dropzone js in my application. i want to restrict only 3 file Upload in my dropzone then work fine.
issue is i upload four Number file then my all previous three file remove. that is not correctly .
i want to only alert in upload (four number file). but previous first three File not remove .
Steps:
1. First three file Upload in dropzon.
2. Add one more File in Dropzone. Then alert mess. only and not Previous File Remove
My Code Here
https://jsfiddle.net/mxxa0bk8/16/
var accept = ".png";
Dropzone.autoDiscover = false;
// Dropzone class:
var myDropzone = new Dropzone("#mydropzone", {
url: "/file/post",
acceptedFiles: accept,
uploadMultiple: false,
createImageThumbnails: false,
addRemoveLinks: true,
maxFiles: 3,
maxfilesexceeded: function(file) {
alert("No moar files please!");
},init: function() {
this.on("maxfilesexceeded", function(file) {
this.removeFile(file);
});
this.on('error', function(file, errorMessage) {
var mypreview = document.getElementsByClassName('dz-error');
mypreview = mypreview[mypreview.length - 1];
mypreview.classList.toggle('dz-error');
mypreview.classList.toggle('dz-success');
});
}
});
The following code snippet will make your dropzone remove files when they are completed:
this.on("complete", function(file) {
this.removeFile(file);
});
Add this right under:
this.on('error', function(file, errorMessage) {
var mypreview = document.getElementsByClassName('dz-error');
mypreview = mypreview[mypreview.length - 1];
mypreview.classList.toggle('dz-error');
mypreview.classList.toggle('dz-success');
});

Direct Upload of Image to S3 after Manual Cropping with Cropper.js

This is my first post, so be gentle! I'm a Rails beginner and clueless with JavaScript/JQuery...
I have a Rails project which requires that the user be able to select a file and be presented with a preview image, which they can then crop as they wish before uploading the cropped image asynchronously.
I have successfully implemented direct upload to S3 using the JQuery FileUpload plugin (following this tutorial) and I am able to present the user with a preview image which they can crop using Cropper.js. However I need help with the last step of uploading the cropped image.
Here is the JS I have so far for handling the image crop/upload to S3:
$(document).ready(function() {
$('.directUpload').find("input:file").each(function(i, elem) {
var fileInput = $(elem);
var form = $(fileInput.parents('form:first'));
var submitButton = form.find('input[type="submit"]');
var progressBar = $("<div class='bar'></div>");
var barContainer = $("<div class='progress'></div>").append(progressBar);
fileInput.after(barContainer);
fileInput.fileupload({
fileInput: fileInput,
url: form.data('url'), //read AWS config via form attributes
type: 'POST',
autoUpload: false, // prevent upload start on file selection
formData: form.data('form-data'),
paramName: 'file',
dataType: 'XML',
replaceFileInput: false,
The code above initializes JQuery FileUpload and passes my S3 configuration data.
Next I use the JQuery FileUpload's 'add' callback to display a preview image/cropbox, and to upload the image to S3 when the user clicks an 'Upload' button:
add: function (e, data) {
if (data.files && data.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('#preview_image').attr('src', e.target.result); // insert preview image
$('#preview_image').cropper() // initialize cropper on preview image
};
reader.readAsDataURL(data.files[0]);
};
$('#upload_image').on('click', function(){
$('#preview_image').cropper('getCroppedCanvas').toBlob(function (blob){
var croppedFile = new File([blob], 'cropped_file.png')
// How do I now get my cropped file data to upload instead of original file?
})
data.submit();
});
},
It is the last part, above, where I am now stuck - I've created a file from the cropped area, but have been unable to find a way to upload it instead of the original image.
The remaining code deals mainly with displaying upload progress and building an image URL that I can save to my database for image retrieval.
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
progressBar.css('width', progress + '%')
},
start: function (e) {
submitButton.prop('disabled', true); //disable submit button while image is loading
progressBar.
css('background', 'green').
css('display', 'block').
css('width', '0%').
text("Loading...");
},
done: function(e, data) {
submitButton.prop('disabled', false);
progressBar.text("Uploading done");
// extract key from S3 XML response and generate URL for image
var key = $(data.jqXHR.responseXML).find("Key").text();
var url = '//' + form.data('host') + '/' + key;
// create hidden field containing image URL, which can then be stored in model
var input = $("<input />", { type:'hidden', name: 'image_url[]', value: url })
form.append(input);
},
fail: function(e, data) {
submitButton.prop('disabled', false);
progressBar.
css("background", "red").
text("Failed");
}
});
This worked for me
var croppedFile = new File([blob], 'cropped_file.png');
data.files[0] = croppedFile;
data.originalFiles[0] = data.files[0];
or just
data.files[0] = new File([blob], 'cropped_file.png');
data.originalFiles[0] = data.files[0];
and then
data.submit()

Cancel, Abort and Retry individual file upload with ResumableJS

I've successfully managed to upload multiple files in chunks to a server using ResumableJS. During the upload process the user is able to see the overall upload progress and the individual file upload percentage. It's also possible to pause/resume the overall upload.
What i would like to now is allow the user to cancel/abort an individual file upload without interrupting the other file uploads.
In ResumableJS website there are some methods that allow to do what i want, but no examples on how to accomplish this.
I have tried the following:
onclick="ResumableFile.abort(); return(false);"
onclick="file.abort(); return(false);"
onclick="this.abort(); return(false);"
How may i abort a specific file upload without interrupting the overall file upload?
UPDATE: Here is my JS code:
var r = new Resumable({
target: 'FileHandler.ashx'
});
// Resumable.js isn't supported, fall back on a different method
if (!r.support)
{}
else
{
// Show a place for dropping/selecting files
$('.resumable-drop').show();
r.assignDrop($('.resumable-drop')[0]);
r.assignBrowse($('.resumable-browse')[0]);
// Handle file add event
r.on('fileAdded', function (file)
{
//// Add the file to the list
$('.resumable-list').append('<li class="resumable-file-' + file.uniqueIdentifier + '">Uploading <span class="resumable-file-name"></span> <span class="resumable-file-progress"></span> <button type="button" id="removeButton" onclick="abortFile();">Remove</button>');
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);
// Actually start the upload
r.upload();
});
//var file = new ResumableFile();
//$("#removeButton").on("click", function ()
//{
// console.log("abort!");
// file.abort();
//});
function abortFile()
{
console.log("abort!");
r.abort();
}
r.on('pause', function ()
{
// Show resume, hide pause main progress bar
});
r.on('complete', function ()
{
// Hide pause/resume when the upload has completed
});
r.on('fileSuccess', function (file, message)
{
// Reflect that the file upload has completed
});
r.on('fileError', function (file, message)
{
// Reflect that the file upload has resulted in error
});
r.on('fileProgress', function (file)
{
// Handle progress for both the file and the overall upload
});
}
With Ruben Rutten's help here is how i solved my issue:
// Handle file add event
r.on('fileAdded', function (file)
{
// Show progress bar
// Show pause, hide resume
//// Add the file to the list
$('.resumable-list').append('<li class="resumable-file-' + file.uniqueIdentifier + '">Uploading <span class="resumable-file-name"></span> <span class="resumable-file-progress"></span> <button type="button" class="removeButton" id="' + file.uniqueIdentifier + '">Remove</button>');
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);
///event to remove file from upload list
$(".removeButton").on("click", function ()
{
for (var i = 0; i < r.files.length; i++)
{
var identifier = $(this).attr("id");
if (r.files[i].uniqueIdentifier == identifier)
{
r.files[i].cancel();
$('.resumable-file-' + identifier).remove();
}
}
});
r.upload();
});
I know this is an old question, but this might help someone:
Looking at your solution, there is a more efficient way to obtain the resumable instance than iterating all of the files:
// event to remove file from upload list
$(".removeButton").on("click", function ()
{
var identifier = $(this).attr("id");
var file = resumable.getFromUniqueIdentifier(identifier);
file.cancel();
$('.resumable-file-' + identifier).remove();
});
If you have your JavaScript file / part, you create a var r = new Resumable(). You should create a function that aborts it, such as
function abortFile() {
r.abort();
}
Then on your button, use onclick="abortFile(); return false;"
I haven't tested it, but it should work.
In case you use jQuery, you could do the following:
<button id="cancelButton">Cancel</button>
<script type="text/javascript">
// Not sure if this works, just to test
var file = new ResumableFile();
$("#cancelButton").on("click", function() {
file.abort();
});
</script>

Removing a file in modern browsers

Problem
I am currently using ( https://github.com/blueimp/jQuery-File-Upload/wiki ) this jQuery HTML5 Uploader.
The basic version, no ui.
The big problem is, that I looked everywhere (Mozilla Developer Network, SO, Google, etc.) and found no solution for removing a files already added via dragNdrop or manually via the file input dialogue.
Why do I want to achieve removing a file?
Because it seems that HTML5 has a kind of "bug".
If you drop / select a file (file input has set multiple) upload it, and then drop / select another file you magically have now the new file twice and it gets uploaded twice.
To prevent this magic file caching the use would have to refresh the page, which is not what someone wants to have for his modern AJAX web app.
What I have tried so far:
.reset()
.remove()
Reset Button
Setting .val() to ''
This seems to be a general HTML5 JS problem not jQuery specific.
Theory
Might it be, that $j('#post').click (I bind / re-bind a lot of times different callbacks), stacks the callbacks methods so that each time the updateFileupload function is called an additional callback is set.
The actual problem would now not rely anymore on the HTML5 upload, it would now rely on my could, miss-binding the .click action on my submit button (id=#post).
If we now call .unbind before each .click there shouldn't be any duplicated callback binding.
Code
Function containing the upload code:
function updateFileupload (type) {
var destination = "";
switch(type)
{
case upload_type.file:
destination = '/wall/uploadfile/id/<?=$this->id?>';
break;
case upload_type.image:
destination = '/wall/upload/id/<?=$this->id?>';
break;
}
$j('#fileupload').fileupload({
dataType: 'json',
url: destination,
singleFileUploads: false,
autoUpload: false,
dropZone: $k(".dropZone"),
done: function (e, data) {
console.log("--:--");
console.log(data.result);
upload_result = data.result;
console.log(upload_result);
console.log("--:--");
console.log(type);
if(type == upload_type.image)
{
var imageName = upload_result.real;
console.log(imageName);
$k.get('/wall/addpicture/id/<?=$this->id ?>/name'+imageName, function(data){
if(data > 0){
console.log("I made it through!");
if(!data.id)
{
$k('#imgUpload').html('');
//$k('#imgPreview').fadeOut();
$k('#newPost').val('');
$k.get("/wall/entry/id/"+data, function(html){
$k('#postList').prepend(html);
});
}
}
});
}
},
send: function(e, data){
var files = data.files;
var duplicates = Array(); // Iterate over all entries and check whether any entry matches the current and add it to duplicates for deletion
for(var i=0; i<data.files.length;i++)
{
for(var j=0;j<data.files.length-1;j++)
{
if(files[i].name == files[j].name && i != j)
{
duplicates.push(j);
}
}
}
if(duplicates.length > 0)
{
for(var i=0;i<duplicates.length;i++)
files.splice(i, 1);
}
console.log("Duplicates");
console.log(duplicates);
},
drop: function(e, data){
console.log("outside");
// $k.each(data.files, function(index, file){
// $k('#imageListDummy').after('<li class="file-small-info-box">'+file.name+'</li>');
// console.log(file);
//
// });
},
add: function(e, data){
upload_data = data;
console.log(data);
$k.each(data.files, function(index, file){
$k('#imageListDummy').after('<li class="file-small-info-box">'+file.name+'</li>');
console.log(file);
});
$j('#post').click(function(event){
upload_data.submit();
if(type == upload_type.image)
{
var file = upload_data.files[0];
console.log("I am here");
console.log(file);
var img = document.createElement("img");
img.src = window.URL.createObjectURL(file);
img.height = 64;
img.width = 64;
img.onload = function(e) {
window.URL.revokeObjectURL(this.src);
}
document.getElementById('imgPreview').appendChild(img);
$k('#imgPreview').show();
}
clickPostCallback(event);
});
$j('#showSubmit').show();
}
});
}
It could be more a browser security issue.
Current file uploads specs don't allow javascript (or anything as far as I know) to tamper with the value of the file field even if to remove it.
So I would imagine any good file uploader would create multiple file upload fields so you can remove the entire field rather than play with the value?
This is speculation though.
Updated answer to Updated Question:
Shouldn't click() only be bound once? you shouldn't need to rebind a click event to a single element '#post' (unless this element changes, in which case it should really be a class). You can place the click() event binding outside of the options for file upload, as long as it's contained in a $(function(){} so it's when the DOM's ready.
Aside from that I'm trying to read the code without any HTML and no experience in multiple file uploading. The best thing to do is try and re-create it on jsfiddle.net, that way others can go in and play around with the code without affecting you and your likely to find the problem while putting the code in there anyway :)

Uploadify and flash issue uploading to remote server

I'm trying to use uploadify to upload images to a remote server. I've have done everything I can think of for the cross scripting issue or whatever.
Here is what i've done.
scriptAccess to 'Always' in the uploadify function.
I have a crossdomain.xml on my ww2 server with uploadify.swf in the root as well.
I have uploaded my javascript jquery lib file to the remote ww2 server and put it in the header
I put the jquery.uploadify.js and the swfobject.js in the root directory as well.
If I try to click the X to cancel a file I get the error: Error calling method on NPObject
Or uploads don't work either.
If anyone can help with this that would be great. If there are any other good flash based or non flash based multi uploaders that will do remote files with no issue please let me know.
Thanks
I managed to figure it out on my own. I will answer it just incase someone else might have this issue because there is very little help even on the authors site for it.
I decided to leave the Flash file on the same server(Web server) because it didnt seem to work putting it on the media server with the javscript files. The js wouldn't work.
So my main server has the uploadify folder still on the server and I only put the php files(uploader.php) I needed to process my images on the media server AND the crossdomain.xml in the root of that server.
Then told uploadify in the parameter settings to point to my uploader.php script on that server.
Everything worked like a charm after that. I took quite a while to figure it out and get passed the errors. Now I can load balance my media.
Hope this helps someone else. Uploadify is a really nice multi file uploader.
You need to change code in your uploadify.js:
/* Original code */
uploadifyCancel:function(ID) {
jQuery(this).each(function() {
document.getElementById(jQuery(this).attr('id') + 'Uploader').cancelFileUpload(ID, true, true, false);
});
},
/*New code */
uploadifyCancel:function(ID){
jQuery(this).each(function(){
document.getElementById(jQuery(this).attr("id")+"Uploader").cancelFileUpload(ID,true,false)
});
},
/*Original code */
jQuery(this).bind("uploadifyComplete", {
'action': settings.onComplete
}, function(event, ID, fileObj, response, data) {
if (event.data.action(event, ID, fileObj, unescape(response), data) !== false) {
jQuery("#" + jQuery(this).attr('id') + ID).find('.percentage').text(' - Completed');
if (settings.removeCompleted) {
jQuery("#" + jQuery(event.target).attr('id') + ID).fadeOut(250,function() {
jQuery(this).remove()
});
}
jQuery("#" + jQuery(event.target).attr('id') + ID).addClass('completed');
}
});
/* New code */
jQuery(this).bind("uploadifyProgress", {
'action': settings.onProgress,
'toDisplay': settings.displayData
}, function(event, ID, fileObj, data) {
if (event.data.action(event, ID, fileObj, data) !== false) {
jQuery("#" + jQuery(this).attr('id') + ID + "ProgressBar").animate({
'width': data.percentage + '%'
},250,function() {
if (data.percentage == 100) {
jQuery(this).closest('.uploadifyProgress').fadeOut(250,function() {
jQuery(this).remove()
});
}
});
if (event.data.toDisplay == 'percentage') displayData = ' - ' + data.percentage + '%';
if (event.data.toDisplay == 'speed') displayData = ' - ' + data.speed + 'KB/s';
if (event.data.toDisplay == null) displayData = ' ';
jQuery("#" + jQuery(this).attr('id') + ID).find('.percentage').text(displayData);
}
});

Categories