蓝色信封文件上传插件中的maxFileSize和acceptFileTypes无效。为什么?

86

我正在使用Blueimp jQuery文件上传插件上传文件。

上传过程没有问题,但是选项maxFileSizeacceptFileTypes无法正常工作。

这是我的代码:

$(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 + '%');
        }
    });
});

你好,我正在尝试实现这个文件上传的代码,但是出现了一个错误,提示说:上传文件错误:上传的字节数超过了文件大小限制请问您能否建议一下是什么原因导致的呢? - Jay Maharjan
2
@JayMaharjan 你确定 maxFileSize 配置正确吗? - YoBre
1
在进行了正确的php.ini配置之后,现在我能够上传大文件了。感谢您的帮助。 :) - Jay Maharjan
对于我的情况,gif 图片被调整大小并转换为 png 格式,因此 gif 过滤器显然失败了。奇怪的是,当我弄清楚发生了什么后,它突然开始自己工作了。我再次检查了库是否有问题,但没有发现任何异常,我只是添加了一些控制台日志,之后又将其删除,但它仍然正常工作。发布这篇文章以帮助其他人。 - Zia Ul Rehman Mughal
15个回答

138

我也遇到了同样的问题,blueimp的人说"maxFileSize和acceptFileTypes仅由UI版本支持",并提供了一个(损坏的)链接来添加_validate和_hasError方法。

因此,不知道如何在不弄乱我编写的脚本的情况下将这些方法合并,我编写了这个小函数。 对我而言,它似乎有效。

只需添加以下内容

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();
        }
},
在你的代码中,将.fileupload选项的开始部分设置如下所示。
$(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 + '%');
        }
    });
});

您会注意到我还添加了一个filesize函数,因为在UI版本中这也是有效的。

更新以解决@lopsided建议的问题:在查询中添加了data.originalFiles [0] ['type'] .lengthdata.originalFiles [0] ['size'] .length,以确保它们存在且不为空,然后再进行错误测试。如果它们不存在,则不会显示任何错误,而只会依赖于您的服务器端错误测试。


这确实非常有用。但是需要注意的是,如果从不支持文件API的浏览器上传,则data.originalFiles [0] ['type']为空。这是我在安卓手机上的情况。我的做法是,如果没有此值,则忽略它,然后回退到服务器端MIME类型验证。否则,您永远无法通过acceptFileTypes.test行。 - lopsided
我没有花太多时间研究这个问题,但我在 jquery.fileupload.js 文件的1073行左右看到 _getSingleFileInputFiles 函数有很多回退来获取文件信息对象。那里有一个注释说 // 如果文件属性不可用,则浏览器不支持 File API,我们将添加一个伪文件对象,其名称为输入值,路径信息已被删除,因此它暗示了您提出的测试(虽然有用且可能适用于 >90% 的用例)并不是100% 可靠的,正如我发现的那样。 - lopsided
8
我认为条件“data.originalFiles [0] ['size'] .length”已经过时,因此它总是返回false。 - kkocabiyik
5
请使用 data.files[0]['size'] 和 data.files[0]['type']。这条指令的意思是获取第一个文件的大小和类型。 - Jose
3
使用不带'length'的方式: (data.originalFiles[0]['size'] && data.originalFiles[0]['size'] > 500000) ? 'true' : 'false' 可以正常工作,但我想知道是否有任何遗漏的情况。
  1. data.originalFiles[0]['size'] ? 'true' : 'false' (1) 对于值为0、null、undefined时返回false。
- Ganesh Arulanantham
显示剩余7条评论

49

4
这似乎是更好的答案。 ;) - thasmo
8
加载脚本的顺序对于出现错误信息非常重要: tmpl.min.js > jquery.ui.widget.js > jquery.iframe-transport.js > jquery.fileupload.js > jquery.fileupload-ui.js > jquery.fileupload-process.js > jquery.fileupload-validate.js - FAjir
3
问题是一样的,你能提供一些实际的工作例子吗? - Vlatko
将脚本加载的顺序改变后,问题得到解决。 - Jim
3
我遇到了同样的问题。我的JS文件按照说明的顺序排列,但我仍然可以上传不符合正则表达式要求且超过文件大小限制的文件。我正在使用最新的FileUpload版本9.10.5和jQuery 1.11.1。 - Mr Pablo
3
我也尝试了,即使所有脚本按正确顺序包含在内也不起作用。 - BadHorsie

10
如之前的回答所建议,我们需要包含两个额外的文件 - jquery.fileupload-process.jsjquery.fileupload-validate.js。然而,由于我需要在添加文件时执行一些额外的ajax调用,因此我订阅了fileuploadadd事件来执行这些调用。关于这样的用法,该插件的作者建议如下:

请看这里:https://github.com/blueimp/jQuery-File-Upload/wiki/Options#wiki-callback-options

通过bind(或使用jQuery 1.7+方法的on方法)添加附加事件侦听器是保留jQuery File Upload UI版本的回调设置的首选选项。

或者,您也可以简单地在自己的回调中启动处理,如下所示:https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload-process.js#L50

使用两种建议选项的组合,以下代码对我非常有效。

$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);
    });
});

1
Amith,我尝试了这个,但是出现了以下错误:未捕获的错误:无法在初始化之前调用fileupload方法;尝试调用方法'process' - TheVillageIdiot
1
这几乎总是意味着在适当的时间没有调用.fileupload()。如果没有看到代码,几乎不可能进行诊断。我建议打开一个新问题并发布相关代码,可以作为jsfiddle。 - Amith George
@TheVillageIdiot 你是在$fileInput.fileupload声明中建立'fileuploadadd'逻辑吗?当我试图将Amith的示例放在这样的东西内部时,我遇到了类似的错误:$('#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); }); ... 当我仔细考虑时,这很明显,但我试图在我还没有完成声明的东西内定义逻辑。 - jdhurst
我遇到了这个错误:Uncaught ReferenceError: makeAjaxCall。 - rida mukhtar

8

这对我在火狐浏览器中有效

$('#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!.');
    }
});

3
欢迎来到Stack Overflow!您能否请将这个答案改成英文?我知道自动翻译有时候很难分辨,但是在这里我们只使用英语(非编程语言)。 - Pops
15
请注意,你不必成为一个狡猾的语言学家才能理解nasatome的意思:“这对我有效:在Firefox中是正确的。” 上传错误信息是“文件大小过大”。我是澳大利亚人,从小就说英语,但我认为有一种特定的英语口音。 “这里只使用英语”并不准确。 这里的人们使用许多不同的语言。 但是,本网站的政策是用英语提问和回答问题。 - Tim Ogilvy

3
如果你已经按照正确的顺序导入了所有插件JS,但仍然遇到问题,那么指定自己的“add”处理程序可能会使* -validate.js插件的处理程序失效,该插件通常通过调用data.process()来触发所有验证。因此,在您的“add”事件处理程序中执行以下操作即可解决问题:
$('#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);
   });
}
...
});

解决了我的问题。 - fezfox

3

打开名为 "jquery.fileupload-ui.js" 的文件,你会看到如下代码:

 $.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',
        。。。。

只需添加一行代码 - 新属性“acceptFileTypes”,如下:

 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

现在你会发现一切都没问题了!~ 你只是把属性放错了位置。


如果可以避免的话,修改插件/库的核心代码是一个不好的想法。 - BadHorsie

2

以下是一个可行的示例,适用于:

  • 多个文件输入
  • 上传一个或多个文件 - 使用$.grep()从带有错误的数组中删除文件
  • 图像音频格式
  • 通过new RegExp()从字符串动态获取文件类型

注意:acceptFileTypes.test() - 检查mime类型,对于像.mp3这样的音频文件,它将是audio/mpeg,而不仅仅是扩展名。有关所有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

1
.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();                    
    }

1
这对我在Chrome中有效,jquery.fileupload.js版本为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();
        }
    },

1
谢谢。它也适用于9.21版本。 - geca

1

如果有人在寻找服务器通常支持的格式

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接