我的$ .ajax请求在iOS 11.3上停止正常工作

时间:2018-03-30 17:24:59

标签: ios ajax

此代码过去常常工作得很好。

鉴于$ .ajax没有收到任何文件数据,从更新到iOS 11.3开始,这个$ .ajax在iOS浏览器上测试时,提交一个简单的纯文本表格似乎非常缓慢,最长可达20秒。

但是如果文件元素传递文件数据,$ .ajax在两种情况下都能正常工作,并且和预期一样快。

HTML ---
<form enctype="multipart/form-data" id="chatform" method="post">
    <input type="file" name="pic" id="pic" class="hidden" />
    <textarea name="chattextarea" id="chattextarea" rows="3" cols="10"></textarea>
    <input type="button" value="Send" onclick="sendMessage();" />
</form>

JavaScript ---
function sendMessage() {
    var formData = new FormData($("#chatform")[0]);
    $.ajax({
        url: 'send.php',
        type: 'POST',
        data: formData,
        async: true,
        cache: false,
        contentType: false,
        processData: false,
        success: function (returndata) {
            /* some success message */
        }
    });
}

这是iOS 11.3错误吗?

-----编辑-----

是的确不仅是iOS 11.3错误,还有Safari 11.1错误。 到目前为止,我测试了这些环境并复制了错误:

  1. Mac OS,Safari
  2. iOS,Safari
  3. iOS,Chrome
  4. iOS,WKWebView(混合应用)
  5. 我写了一个简单的解决方法,请检查我的答案,如果你有更清洁的解决方案,请告诉我。

8 个答案:

答案 0 :(得分:3)

我没有删除,而是在创建类之前禁用了formData中的空文件输入:

if(!file.val()){
   file.attr('disabled', true);
}

答案 1 :(得分:3)

此功能适用于iOS 11.3,iOS 10.2和Windows Chrome 65.0.3325.181。 有人可以帮助在其他浏览器上测试吗?

function formDataFileFix(formData) {
    try {
        if (formData.keys) {
            var formKeysToBeRemoved = [];
            for (var key of formData.keys()) {
                var fileName = null || formData.get(key)['name'];
                var fileSize = null || formData.get(key)['size'];
                if (fileName != null && fileSize != null && fileName == '' && fileSize == 0) {
                    formKeysToBeRemoved.push(key);
                }
            }
            for (var i = 0; i < formKeysToBeRemoved.length; i++) {
                formData.delete(formKeysToBeRemoved[i]);
            }
        }
    }
    catch(err) {
        console.log(err.message);
    }
}

var formData = new FormData($(formID)[0]);
formDataFileFix(formData);

答案 2 :(得分:0)

我有完全相同的问题!我有一个Web应用程序,有几种形式,如果用户不选择包含文件,它将不再起作用。自beta 1以来一直在运行iOS 11.3测试版,并希望每个新测试版都能解决这个问题。相当恼人的是,这个问题在公开发布中仍然存在。希望当这个“bug”影响到更多的人时,会有更多关于如何解决这个问题的信息。

答案 3 :(得分:0)

这里的问题相同!!!由于许多IOS用户正在升级,这将是一个真正的问题。有人找到解决此问题的方法吗?如果我发送文件,则有效。

答案 4 :(得分:0)

我的解决方法是在选择和不选择文件的情况下分离表单的行为。

这个解决方案非常讨厌,但它适用于Apple bug :(

function sendMessage() {
    // Form does not have file selected
    if(!$("#pic").val()) {
        var formData = $("#chatform").serialize();
        $.post("send.php", formData, function(data) {
            /* success */
        });
    }
    // Form has file selected
    else {
        var formData = new FormData($("#chatform")[0]);
        $.ajax({
            url: 'send.php',
            type: 'POST',
            data: formData,
            async: true,
            cache: false,
            contentType: false,
            processData: false,
            success: function (data) {
                /* success */
            }
        });
    }
}

如果您有更清洁的解决方案,请告诉我。

答案 5 :(得分:0)

只需从formData:

中删除空文件输入
if(!imageUsed){
   formData.delete('file[]');
}

我们仍在不同设备上进行测试,但它似乎有效。

答案 6 :(得分:0)

谢谢!我将之前的两个答案合并为一个更清洁,更有效的例子。我认为Apple应该匆忙解决这个问题......

    var formData = new FormData( this );

    if(!$("#image").val()) {
    formData.delete('image_file');
    }

    if(!$("#pdf").val()) {
    formData.delete('pdf_doc');
    }

    $.ajax({
    type: 'post',
    data: formData
    //and so on...

答案 7 :(得分:0)

我遇到了同样的问题,这对我有用,我希望我的解决方案可以帮助任何人:

在Ajax请求之前:

// disable all empty inputs with type file : 

 let fileInputs = document.querySelectorAll(".myForm input[type=file]");
        fileInputs.forEach(function (file) {

            let fileInput =  $('#'+file.id);
            if(fileInput.get(0).files.length === 0){
                fileInput.attr('disabled',true);
            }

        });

然后在这里发出常规的Ajax请求。

注意:之后,您可能需要再次使用类型文件启用输入。 (您禁用它们的方式相同)

 let myFiles = document.querySelectorAll(".myForm input[type=file]");
        myFiles.forEach(function (file) {
            let fileInput =  $('#'+file.id);
            fileInput.attr('disabled',false);
        });