此代码过去常常工作得很好。
鉴于$ .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错误。 到目前为止,我测试了这些环境并复制了错误:
我写了一个简单的解决方法,请检查我的答案,如果你有更清洁的解决方案,请告诉我。
答案 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);
});