当前位置: 首页 > 面试题库 >

发送包含Safari 10.13.4中的空文件的FormData()时,AJAX请求失败

诸葛砚文
2023-03-14
问题内容

我正在运行一个基于Symfony 2.8的Web应用程序,该应用程序使用Ajax将一些表单数据发送回控制器。

到目前为止,一切工作正常,但是由于最新的macOS更新至版本10.13.4,用户开始报告,因此提交表单在Safari中不再起作用。10.13.4上的其他macOS版本和其他浏览器仍然可以正常工作,因此在Safari中似乎是一个问题。我当然向苹果提交了错误报告,但我认为我永远不会从那里得到反馈…

我能够找出问题的根源:提交包含空文件输入的数据失败:

// safri_bug.html
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    </head>
<body>
    <form name="app_booking" method="post" action="/test/submit.php">
        <div><input type="text" id="someValue" name="value"></div>
        <div><input id="thefile" type="file" name="file"></div>
    </form>

    <button id="bSubmit" type="button">Submit</button>

    <script>    
        $(document).ready(function() {              
            $('#bSubmit').click(function() {
                var form = $('form');
                var data = new FormData(form[0]);

                $.ajax({
                    url : '/submit.php',
                    type : 'POST',
                    data : data,
                    contentType: false,
                    processData: false,
                    context : this,
                    success : function(response) {
                            alert('success: ' + response);
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                            alert('error: ' + xhr.responseText + ' - ' + thrownError);
                    }
                });
            });
        });
    </script>
</body>
</html>


// submit.php
<?php 
    echo "OK";

结果

  • 在所有经过测试的浏览器和平台上,但在macOS 10.13.4的Safari中,提交表单都可以正常工作
  • 在macOS 10.13.4上的Safari中:
    • 如果未选择文件:Ajax请求将运行大约20秒钟(是否建立超时?),然后返回带有空的成功响应。该submit.php不会 被调用。
    • 如果选择了文件:一切正常…

因此,这似乎是最新的Safari更新中的错误? 还是我的代码有什么问题?

知道如何防止此错误吗?


问题答案:

同时,我找到了这种快速而肮脏的解决方案。但是实际上我正在寻找一个真正的解决方法。有任何想法吗?

// 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) {}


 类似资料:
  • 问题内容: XMLHttpRequest的2级标准(还是一个工作草案)定义FormData的接口。该接口允许将对象附加到XHR请求(Ajax请求)。 顺便说一句,这是一个新功能-过去曾使用过(请在我的另一个问题中阅读)。 它是这样工作的(示例): 哪里是字段,并且是Ajax请求的成功处理者。 在所有浏览器中(同样,除IE之外),它都能很好地工作。 现在,我想使此功能与jQuery一起使用。我尝试了

  • 问题内容: 我有多个Ajax请求每分钟都有一些请求数据,而其他请求是由用户通过ui发起的。 该请求可能由于身份验证失败而失败。我设置了一个全局方法来捕获任何失败的请求。 发现错误后,我将重置授权。重置授权是可行的,但是用户必须手动重新启动ajax调用(通过ui)。 如何使用最初发送的jqxhr重新发送失败的请求? (我将jQuery用于Ajax) 问题答案: 发现此帖子表明可以很好地解决此问题。

  • 交互过程中,发送请求是第一步。那么,我们将如何构造一个请求呢? 这一章节,我们将一步一步来构建一个 Ajax 请求。学习本节,你将学会: 如何通过 XMLHttpRequest 和 ActiveXObject 来构造一个通用的 xhr 对象。 如何通过 xhr 对象来发送 GET、 POST 等请求。 Content-type 在 Ajax 数据发送中的作用。 那么,接下来让我们进入本节的学习吧。

  • 我有一个带有更新方法的控制器。该方法应在RequestBody中获取产品,但这会导致请求错误。我和邮递员一起发了一封邮件。JSON作为原始JSON发送,请求内容类型为application/JSON。 正文中的JSON是 请求响应不良的原因是什么?JSON似乎格式化正确,当没有正文时调用更新方法。

  • 问题内容: 我需要使用ajax和FormData发送一些数据,因为我想发送文件和其他一些参数。我通常发送数据的方式是这样的: 如果我不使用FormData(),就没有问题,但是当使用FormData()时,只有Lvl1上的数据可以,但是嵌套的任何内容都显示为这样的字符串 如果我使用FormData()对Lvl1-3中的数据进行编码,而不是得到 如何在Lvl1-3上获取数组而不是字符串? 注意:如果

  • 代码如下: 这将向flask发送一个{“name”:“go”}JSON字典。Flask应该将语言名称追加到数组中,并在响应中返回完整的数组。现在,当我手动发送请求时,这就工作了,所以这不是Flask的错误。但是当我从iOS发送上述内容时,我在flask控制台中得到request.json==None。很明显,我送的是一具空尸体,但我不应该。你知道我哪里出了问题吗?