AJAX request fails when sending FormData() including empty file input in Safari 10.13.4

前端 未结 5 1199
一生所求
一生所求 2020-12-14 10:48

I am running a Symfony 2.8 based web app which sends some form data back to a controller using Ajax.

So far everything worked fine, but since the latest macOS update

相关标签:
5条回答
  • 2020-12-14 11:11

    Meanwhile I found this quick and dirty solution. But actually I am looking for a real workaround. Any ideas?

    // Filter out empty file just before the Ajax request
    // Use try/catch since Safari < 10.13.4 does not support FormData.entries()
    try {
       for (var pair of data.entries()) {
          if (pair[1] instanceof File && pair[1].name == '' && pair[1].size == 0)
             data.delete(pair[0]);  
       }
    } catch(e) {}
    
    0 讨论(0)
  • 2020-12-14 11:12

    I used this solution and works for me.

    var $form = $('#website_settings_form');
    var $inputs = $('input[type="file"]:not([disabled])', $form); //select input files
        $inputs.each(function(_, input) {
            if (input.files.length > 0) return 
            $(input).prop('disabled', true) //if the input doesn't have uploaded files will be disable
        })
        var formData = new FormData($form[0]);// create the form data
        $inputs.prop('disabled', false);//enable fields again.
    
    0 讨论(0)
  • 2020-12-14 11:15

    I use FormData throughout my site and can verify that this is a problem with the latest version of Safari. Removing the empty file fixes the problem. Here's the code that worked for me:

      var form = $('#formID');
      var data = new FormData(form[0])
    
      //hack to fix safari bug where upload fails if file input is empty
      if (document.getElementById("fileID").files.length == 0 ) { //if the file is empty
          data.delete('fileID'); //remove it from the upload data
      }
    
    0 讨论(0)
  • 2020-12-14 11:18

    Andrei Herford's solution will crash other browsers that do not support the entries() method of FormData - using try/catch will only find execution errors, not syntax errors.

    Our solution was to use plain JavaScript to remove the empty file input element before creating the FormData object, thus:

    for (i = 0; i < form.elements.length; i++) {
      if (form.elements[i].type == 'file') {
        if (form.elements[i].value == '') {
          form.elements[i].parentNode.removeChild(form.elements[i]);
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-14 11:29

    I used Andrei's suggestion, which worked for safari, but broke IE.

    The only solution I could find that would work in both browsers was to use eval().

    Since this appears to be a bug only affecting safari 11 I also added a check on browser version.

    if(dataObj instanceof FormData && navigator.userAgent.match(/version\/11((\.[0-9]*)*)? .*safari/i)) {
        try {
            eval('for (var pair of dataObj.entries()) {\
                if (pair[1] instanceof File && pair[1].name === \'\' && pair[1].size === 0) {\
                    dataObj.delete(pair[0]);\
                }\
            }');
        } catch(e) {}
    }
    
    0 讨论(0)
提交回复
热议问题