Estoy usando el complemento de carga de archivos Blueimp jQuery para cargar archivos.
No tuve ningún problema en subir pero la opción maxFileSize
ya acceptFileTypes
no funciona.
Este es mi codigo:
$(document).ready(function () {
'use strict';
$('#fileupload').fileupload({
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
maxFileSize: 5000000,
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p style="color: green;">' + file.name + '<i class="elusive-ok" style="padding-left:10px;"/> - Type: ' + file.type + ' - Size: ' + file.size + ' byte</p>')
.appendTo('#div_files');
});
},
fail: function (e, data) {
$.each(data.messages, function (index, error) {
$('<p style="color: red;">Upload file error: ' + error + '<i class="elusive-remove" style="padding-left:10px;"/></p>')
.appendTo('#div_files');
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css('width', progress + '%');
}
});
});
Respuestas:
Tuve el mismo problema, y el tipo de blueimp dice " maxFileSize y acceptFileTypes solo son compatibles con la versión de UI " y ha proporcionado un enlace (roto) para incorporar los métodos _validate y _hasError.
Entonces, sin saber cómo incorporar esos métodos sin estropear el script, escribí esta pequeña función. Parece funcionar para mí.
Solo agrega esto
add: function(e, data) { var uploadErrors = []; var acceptFileTypes = /^image\/(gif|jpe?g|png)$/i; if(data.originalFiles[0]['type'].length && !acceptFileTypes.test(data.originalFiles[0]['type'])) { uploadErrors.push('Not an accepted file type'); } if(data.originalFiles[0]['size'].length && data.originalFiles[0]['size'] > 5000000) { uploadErrors.push('Filesize is too big'); } if(uploadErrors.length > 0) { alert(uploadErrors.join("\n")); } else { data.submit(); } },
al comienzo de las opciones .fileupload como se muestra en su código aquí
$(document).ready(function () { 'use strict'; $('#fileupload').fileupload({ add: function(e, data) { var uploadErrors = []; var acceptFileTypes = /^image\/(gif|jpe?g|png)$/i; if(data.originalFiles[0]['type'].length && !acceptFileTypes.test(data.originalFiles[0]['type'])) { uploadErrors.push('Not an accepted file type'); } if(data.originalFiles[0]['size'].length && data.originalFiles[0]['size'] > 5000000) { uploadErrors.push('Filesize is too big'); } if(uploadErrors.length > 0) { alert(uploadErrors.join("\n")); } else { data.submit(); } }, dataType: 'json', autoUpload: false, // acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, // maxFileSize: 5000000, done: function (e, data) { $.each(data.result.files, function (index, file) { $('<p style="color: green;">' + file.name + '<i class="elusive-ok" style="padding-left:10px;"/> - Type: ' + file.type + ' - Size: ' + file.size + ' byte</p>') .appendTo('#div_files'); }); }, fail: function (e, data) { $.each(data.messages, function (index, error) { $('<p style="color: red;">Upload file error: ' + error + '<i class="elusive-remove" style="padding-left:10px;"/></p>') .appendTo('#div_files'); }); }, progressall: function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $('#progress .bar').css('width', progress + '%'); } }); });
Notarás que también agregué una función allí porque eso también solo funcionará en la versión de interfaz de usuario.
Actualizado para superar el problema sugerido por @lopsided: agregado
data.originalFiles[0]['type'].length
ydata.originalFiles[0]['size'].length
en las consultas para asegurarse de que existan y no estén vacías primero antes de probar los errores. Si no existen, no se mostrará ningún error y solo se basará en las pruebas de error del lado del servidor.fuente
data.originalFiles[0]['type']
está vacío cuando se carga desde un navegador que no es compatible con la API de archivos. Este fue el caso de mi teléfono Android. Lo que hice fue pasarlo si este valor no está disponible y luego volver a la validación del tipo mime del lado del servidor. De lo contrario, nunca pasará de laacceptFileTypes.test
líneaDebe incluir jquery.fileupload-process.js y jquery.fileupload-validate.js para que funcione.
fuente
Como se sugirió en una respuesta anterior, debemos incluir dos archivos adicionales,
jquery.fileupload-process.js
y luego, sinjquery.fileupload-validate.js
embargo, como necesito realizar algunas llamadas ajax adicionales mientras agrego un archivo, me suscribo alfileuploadadd
evento para realizar esas llamadas. Con respecto a tal uso, el autor de este complemento sugirió lo siguienteUsando la combinación de las dos opciones sugeridas, el siguiente código funciona perfectamente para mí
$fileInput.fileupload({ url: 'upload_url', type: 'POST', dataType: 'json', autoUpload: false, disableValidation: false, maxFileSize: 1024 * 1024, messages: { maxFileSize: 'File exceeds maximum allowed size of 1MB', } }); $fileInput.on('fileuploadadd', function(evt, data) { var $this = $(this); var validation = data.process(function () { return $this.fileupload('process', data); }); validation.done(function() { makeAjaxCall('some_other_url', { fileName: data.files[0].name, fileSizeInBytes: data.files[0].size }) .done(function(resp) { data.formData = data.formData || {}; data.formData.someData = resp.SomeData; data.submit(); }); }); validation.fail(function(data) { console.log('Upload error: ' + data.files[0].error); }); });
fuente
Uncaught Error: cannot call methods on fileupload prior to initialization; attempted to call method 'process'
.fileupload()
no se llamó en el momento adecuado. Sin ver el código, es casi imposible de diagnosticar. Sugiero abrir una nueva pregunta y publicar el código relevante, tal vez como jsfiddle.$('#fileupload').fileupload({ blah : blah, blah : blah, }) $fileInput.on('fileuploadadd', function(evt, data) { var $this = $(this); var validation = data.process(function () { return $this.fileupload('process', data); }); ...
era obvio cuando lo pensaba, pero estaba tratando de definir la lógica dentro de algo que aún no había terminado de declarar.Esto me funciona en Firefox
$('#fileupload').fileupload({ dataType: 'json', //acceptFileTypes: /(\.|\/)(xml|pdf)$/i, //maxFileSize: 15000000, add: function (e, data) { var uploadErrors = []; var acceptFileTypes = /\/(pdf|xml)$/i; if(data.originalFiles[0]['type'].length && !acceptFileTypes.test(data.originalFiles[0]['type'])) { uploadErrors.push('File type not accepted'); } console.log(data.originalFiles[0]['size']) ; if (data.originalFiles[0]['size'] > 5000000) { uploadErrors.push('Filesize too big'); } if(uploadErrors.length > 0) { alert(uploadErrors.join("\n")); } else { data.context = $('<p/>').text('Uploading...').appendTo(document.body); data.submit(); } }, done: function (e, data) { data.context.text('Success!.'); } });
fuente
abra el archivo llamado "jquery.fileupload-ui.js", verá el código como este:
$.widget('blueimp.fileupload', $.blueimp.fileupload, { options: { // By default, files added to the widget are uploaded as soon // as the user clicks on the start buttons. To enable automatic // uploads, set the following option to true: acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, autoUpload: false, // The ID of the upload template: uploadTemplateId: 'template-upload', // The ID of the download template: downloadTemplateId: 'template-download', 。。。。
simplemente agregue un código de línea --- el nuevo atributo "acceptFileTypes", como este:
options: { // By default, files added to the widget are uploaded as soon // as the user clicks on the start buttons. To enable automatic // uploads, set the following option to true: **acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,** autoUpload: false, // The ID of the upload template: uploadTemplateId: 'template-upload', // The ID of the download template: downloadTemplateId: 'template-d
¡Ahora verás que todo está bien! ~ simplemente tomas el atributo en el lugar equivocado.
fuente
Si tiene todos los JS del complemento importados y en el orden correcto, pero todavía tiene problemas, parece que especificar su propio controlador "agregar" debilita el del complemento * -validate.js, que normalmente se dispararía desactiva toda la validación llamando a data.process (). Entonces, para solucionarlo, haga algo como esto en su controlador de eventos "agregar":
$('#whatever').fileupload({ ... add: function(e, data) { var $this = $(this); data.process(function() { return $this.fileupload('process', data); }).done(function(){ //do success stuff data.submit(); <-- fire off the upload to the server }).fail(function() { alert(data.files[0].error); }); } ... });
fuente
Ejemplo verificado / válido para:
$.grep()
para eliminar archivos de la matriz con erroresimage
yaudio
formatonew RegExp()
Aviso:
acceptFileTypes.test()
- verifique los tipos de mime, para ver el archivo adio como.mp3
seráaudio/mpeg
, no solo la extensión. Para todas las opciones de blueimp: https://github.com/blueimp/jQuery-File-Upload/wiki/Options$('input[type="file"]').each(function(i){ // .form_files is my div/section of form for input file and progressbar var $progressbar = $(this).parents('.form_files:first').find('.progress-bar:first'); var $image_format = 'jpg|jpeg|jpe|png|gif'; var $audio_format = 'mp3|mpeg'; var $all_formats = $image_format + '|' + $audio_format; var $image_size = 2; var $audio_size = 10; var mb = 1048576; $(this).fileupload({ // ... singleFileUploads: false, // << send all together, not single // ... add: function (e, data) { // array with all indexes of files with errors var error_uploads_indexes = []; // when add file - each file $.each(data.files, function(index, file) { // array for all errors var uploadErrors = []; // validate all formats first if($all_formats){ // check all formats first - before size var acceptFileTypes = "(\.|\/)(" + $all_formats + ")$"; acceptFileTypes = new RegExp(acceptFileTypes, "i"); // when wrong format if(data.files[index]['type'].length && !acceptFileTypes.test(data.files[index]['type'])) { uploadErrors.push('Not an accepted file type'); }else{ // default size is image_size var $my_size = $image_size; // check audio format var acceptFileTypes = "(\.|\/)(" + $audio_format + ")$"; acceptFileTypes = new RegExp(acceptFileTypes, "i"); // alert(data.files[index]['type']); // alert(acceptFileTypes.test('audio/mpeg')); // if is audio then size is audio_size if(data.files[index]['type'].length && acceptFileTypes.test(data.files[index]['type'])) { $my_size = $audio_size; } // check size if(data.files[index]['size'] > $my_size * mb) { uploadErrors.push('Filesize is too big'); }; }; }; // << all_formats // when errors if(uploadErrors.length > 0) { // alert(uploadErrors.join("\n")); // mark index of error file error_uploads_indexes.push(index); // alert error alert(uploadErrors.join("\n")); }; }); // << each // remove indexes (files) with error data.files = $.grep( data.files, function( n, i ) { return $.inArray(i, error_uploads_indexes) ==-1; }); // if are files to upload if(data.files.length){ // upload by ajax var jqXHR = data.submit().done(function (result, textStatus, jqXHR) { //... alert('done!') ; // ... }); } // }, // << add progressall: function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $progressbar.css( 'width', progress + '%' ); } }); // << file_upload // }); // << each input file
fuente
Solo un ejemplo de controlador de eventos para Agregar evento. Asume que la opción singleFileUploads está habilitada (que es la predeterminada). Lea más documentación de carga de archivos de jQuery sobre cómo enlazar con el evento add / fileuploadadd. Dentro del bucle puede usar tanto vars this como file . Un ejemplo de cómo obtener la propiedad de tamaño: este ['tamaño'] o file.size .
/** * Handles Add event */ base.eventAdd = function(e, data) { var errs = []; var acceptFileTypes = /(\.|\/)(gif|jpe?g|png)$/i; var maxFileSize = 5000000; // Validate file $.each(data.files, function(index, file) { if (file.type.length && !acceptFileTypes.test(file.type)) { errs.push('Selected file "' + file.name + '" is not alloawed. Invalid file type.'); } if (this['size'] > maxFileSize) { errs.push('Selected file "' + file.name + '" is too big, ' + parseInt(file.size / 1024 / 1024) + 'M.. File should be smaller than ' + parseInt(maxFileSize / 1024 / 1024) + 'M.'); } }); // Output errors or submit data if (errs.length > 0) { alert('An error occured. ' + errs.join(" ")); } else { data.submit(); } };
fuente
Esto funcionó para mí en Chrome, la versión jquery.fileupload.js es 5.42.3
add: function(e, data) { var uploadErrors = []; var ext = data.originalFiles[0].name.split('.').pop().toLowerCase(); if($.inArray(ext, ['odt','docx']) == -1) { uploadErrors.push('Not an accepted file type'); } if(data.originalFiles[0].size > (2*1024*1024)) {//2 MB uploadErrors.push('Filesize is too big'); } if(uploadErrors.length > 0) { alert(uploadErrors.join("\n")); } else { data.submit(); } },
fuente
.fileupload({ add: function (e, data) { var attachmentValue = 3 * 1000 * 1024; var totalNoOfFiles = data.originalFiles.length; for (i = 0; i < data.originalFiles.length; i++) { if (data.originalFiles[i]['size'] > attachmentValue) { $attachmentsList.find('.uploading').remove(); $attachmentMessage.append("<li>" + 'Uploaded bytes exceeded the file size' + "</li>"); $attachmentMessage.show().fadeOut(10000, function () { $attachmentMessage.html(''); }); data.originalFiles.splice(i, 1); } } if (data.files[0]) { $attachmentsList .prepend('<li class="uploading" class="clearfix loading-content">' + data.files[0].name + '</li>'); } data.submit(); }
fuente
En caso de que alguien busque formatos comúnmente compatibles con el servidor
3g2|3gp|3gp2|3gpp|aac|aaf|aca|accdb|accde|accdt|acx|adt|adts|afm|ai|aif|aifc|aiff|appcache|application|art|asd|asf|asi|asm|asr|asx|atom|au|avi|axs|bas|bcpio|bin|bmp|c|cab|calx|cat|cdf|chm|class|clp|cmx|cnf|cod|cpio|cpp|crd|crl|crt|csh|css|csv|cur|dcr|deploy|der|dib|dir|disco|dll|dllconfig|dlm|doc|docm|docx|dot|dotm|dotx|dsp|dtd|dvi|dvr-ms|dwf|dwp|dxr|eml|emz|eot|eps|esd|etx|evy|exe|execonfig|fdf|fif|fla|flr|flv|gif|gtar|gz|h|hdf|hdml|hhc|hhk|hhp|hlp|hqx|hta|htc|htm|html|htt|hxt|ico|ics|ief|iii|inf|ins|isp|IVF|jar|java|jck|jcz|jfif|jpb|jpe|jpeg|jpg|js|json|jsonld|jsx|latex|less|lit|lpk|lsf|lsx|lzh|m13|m14|m1v|m2ts|m3u|m4a|m4v|man|manifest|map|mdb|mdp|me|mht|mhtml|mid|midi|mix|mmf|mno|mny|mov|movie|mp2|mp3|mp4|mp4v|mpa|mpe|mpeg|mpg|mpp|mpv2|ms|msi|mso|mvb|mvc|nc|nsc|nws|ocx|oda|odc|ods|oga|ogg|ogv|one|onea|onepkg|onetmp|onetoc|onetoc2|osdx|otf|p10|p12|p7b|p7c|p7m|p7r|p7s|pbm|pcx|pcz|pdf|pfb|pfm|pfx|pgm|pko|pma|pmc|pml|pmr|pmw|png|pnm|pnz|pot|potm|potx|ppam|ppm|pps|ppsm|ppsx|ppt|pptm|pptx|prf|prm|prx|ps|psd|psm|psp|pub|qt|qtl|qxd|ra|ram|rar|ras|rf|rgb|rm|rmi|roff|rpm|rtf|rtx|scd|sct|sea|setpay|setreg|sgml|sh|shar|sit|sldm|sldx|smd|smi|smx|smz|snd|snp|spc|spl|spx|src|ssm|sst|stl|sv4cpio|sv4crc|svg|svgz|swf|t|tar|tcl|tex|texi|texinfo|tgz|thmx|thn|tif|tiff|toc|tr|trm|ts|tsv|ttf|tts|txt|u32|uls|ustar|vbs|vcf|vcs|vdx|vml|vsd|vss|vst|vsto|vsw|vsx|vtx|wav|wax|wbmp|wcm|wdb|webm|wks|wm|wma|wmd|wmf|wml|wmlc|wmls|wmlsc|wmp|wmv|wmx|wmz|woff|woff2|wps|wri|wrl|wrz|wsdl|wtv|wvx|x|xaf|xaml|xap|xbap|xbm|xdr|xht|xhtml|xla|xlam|xlc|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm|xltx|xlw|xml|xof|xpm|xps|xsd|xsf|xsl|xslt|xsn|xtp|xwd|z|zip
fuente
También puede usar una función adicional como:
function checkFileType(filename, typeRegEx) { if (filename.length < 4 || typeRegEx.length < 1) return false; var filenameParts = filename.split('.'); if (filenameParts.length < 2) return false; var fileExtension = filenameParts[filenameParts.length - 1]; return typeRegEx.test('.' + fileExtension); }
fuente
Debe incluir jquery.fileupload-process.js y jquery.fileupload-validate.js para que funcione.
Entonces...
$(this).fileupload({ // ... processfail: function (e, data) { data.files.forEach(function(file){ if (file.error) { self.$errorMessage.html(file.error); return false; } }); }, //... }
La devolución de llamada de processfail se inicia después de un error de validación.
fuente
Una forma más sencilla sería hacer algo como se indica a continuación dentro de add:
add : function (e,data){ var extension = data.originalFiles[0].name.substr( (data.originalFiles[0].name.lastIndexOf('.') +1) ); switch(extension){ case 'csv': case 'xls': case 'xlsx': data.url = <Your URL>; data.submit(); break; default: alert("File type not accepted"); break; } }
fuente
si tiene varios archivos, usa un bucle para verificar cada uno de los formatos de archivo, algo como esto
add: function(e, data) { data.url = 'xx/'; var uploadErrors = []; var acceptFileTypes = /^image\/(gif|jpe?g|png)$/i; console.log(data.originalFiles); for (var i = 0; i < data.originalFiles.length; i++) { if(data.originalFiles[i]['type'].length && !acceptFileTypes.test(data.originalFiles[i]['type'])) { uploadErrors.push('Not an accepted file type'); data.originalFiles } if(data.originalFiles[i]['size'].length && data.originalFiles[i]['size'] > 5000000) { uploadErrors.push('Filesize is too big'); } if(uploadErrors.length > 0) { alert(uploadErrors.join("\n")); } } data.submit(); },
fuente