Chrome文件上传漏洞:在选择相同文件时,change事件不会被执行两次。

24

我正在开发一个HTML5文件上传插件,但是在Google Chrome上有一个bug,我无法理解和修复它。 在Firefox上运行良好。

jsfiddle链接

问题是你无法从桌面上传相同的文件两次

当你第一次点击选择并点击“确定”从桌面上传一个文件时,它应该弹出一个消息,例如'.button-1' - 取决于你点击的上传按钮。

然后,如果你尝试再次上传相同的文件,这行代码将不再执行:

$(".upload-file",object_parent).change(function() {

             ...
             ...

             alert($cm.selector);

});

这个插件出了什么问题?

(function($){

    // Attach this new method to jQuery
    $.fn.extend({ 

        // This is where you write your plugin's name
        upload_file_html5: function(options) {

            // Set the default values, use comma to separate the settings, example:
            var defaults = {
                objectSuperparent:    '.media'
            }

            var options =  $.extend(defaults, options);
            var o = options;

            var $cm = this.click(function(e){

                // <a> button is the object in this case.
                var object = $(this);

                // Get other info from the element belong to this object group.
                var object_href = object.attr('href');
                var object_parent = object.parent();
                alert($cm.selector);

                // Trigger the click event on the element.
                // Due to security policies triggering click on the input type=file is not allowed/supported in some browsers and Opera is one of them.
                //$('input[type=file]').trigger('click'); // or:
                $(".upload-file",object_parent).click();

                return false;

            });

            // Trigger ajax post when ever the file is changed by the user.
            var $cm_2 = $(".upload-file").change(function(){

                // <input> is the object in this case.
                var object = $(this);

                var object_form = object.parent();
                var object_superparent = object.parents(o.objectSuperparent);
                var path_config = $($cm.selector,object_superparent).attr('href');
                var path_post = object_form.attr('action');

                alert($cm.selector);
                //alert(path_config);

                ....
                ....

            });

        }
    });

})(jQuery);

在Chrome上它之前运行正常,但是最近突然就不行了,可能是Chrome已经向我的电脑更新了最新版本,这个更新导致了这个bug吗?

4个回答

50

如果您想上传两次,请清除文件输入的值

$('input[type="file"]').val(null);

jsfiddle测试


我会移除jsfiddle链接,"objectSuperparent"和所有的代码有点让人困惑。 - Avatar
谢谢,这个问题让我快要抓狂了! - NateQ

18

是的,我的Chrome和Firefox的行为不同,但我认为Chrome是正确的。

根据 W3C文档 的规定:

当控件失去输入焦点并且自获得焦点以来其值已被修改时,会触发 onchange 事件。

如果您尝试上传相同的文件,则文件输入的值不会更改。尝试将其打印出来:

$('.button-2').click(function(){
    console.log($(".list .upload-file").val())
    return false;
});

1
谢谢。那我不能使用 onchange 事件吗?还有其他方法可以让我上传同一个文件吗?谢谢 :-) - Run
请参考@fundon的答案(https://dev59.com/Nmox5IYBdhLWcg3whUkV#11280864)以获取可行的解决方案。 - Steven Xu
是的,我正在选择相同的文件。 - bresleveloper

2
可能是输入正在重新渲染。无论出于什么原因,对我来说都不重要。$.on('change', callback)功能丢失。
尝试使用.delegate函数,我非常喜欢!http://api.jquery.com/delegate/ 好的,delegate完全相同,它只是告诉jQuery,如果屏幕上呈现具有特定句柄的元素,请将功能附加到它。
因此,即使元素被重新呈现,它仍将保持其功能。
$(document).delegate('.file_upload_btn', 'change', function(){});

您可能认为这只是一个可有可无的功能,会问有什么区别,但对于我的项目来说,这个功能节省了我很多时间。

0

这个问题可能是由于文件没有改变,onchange函数没有被触发所引起的。可以通过在每次上传后清除值来解决这个问题。

<input type="file" onChange={handelChange}/>

function handelChange(event){
//your logic here

//on finish
e.target.value="" // this works!



// e.taget.value=null doesn't work for some reason
}

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