iOS Safari无法通过AJAX发送表单数据

Sim*_*ran 1 javascript forms ajax ios

我正在尝试使用JavaScript通过Ajax提交表单.它适用于Browserstack中的IE,Firefox,Chrome和iOS,但它不适用于iOS模拟器或真正的iOS设备或桌面Safari.

我试过XMLHttpRequest onloadXMLHttpRequest onreadystatechange,既没有被触发.据我所知,request.open('POST', url, true);是不行的.console.log('2');永远不会被触发.

我添加了这个用于调试:

request.send(data);
console.log(request);
setTimeout(function(){ console.log(request); }, 3000);
Run Code Online (Sandbox Code Playgroud)

它们都在Safari中返回readyState:1,在其他浏览器中,第一个返回readyState:1,第二个返回readyState:4,如预期的那样.

这是我的代码简化为要点:

$('.ajax-form').submit(function(event) {
  var form = event.target;
  var data = new FormData(form);
  var request = new XMLHttpRequest();
  var method = form.getAttribute("method");
  var action = form.getAttribute("action");
  var url = window.location.href
  request.open('POST', url, true);
  request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  request.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest");
  request.setRequestHeader("pragma", "no-cache");
  console.log('1');
  request.onreadystatechange = function() {
    console.log('2');
    if (request.readyState === 4 && request.status === 200) {
      var response = JSON.parse(request.response);

      if (response.success && response.finished) {
        // Go to selected success page
        window.location.href = $(form).find('[name="formReturnUrl"]').attr('value');

      } else if (response.errors || response.formErrors) {
        // Deal with errors
      }
    }
  };

  request.send(data);
  console.log(request);
  setTimeout(function() {
    console.log(request);
  }, 3000);
  event.preventDefault();
});
Run Code Online (Sandbox Code Playgroud)

我的所有iOS测试都在Safari的iOS 11上进行.我读过一些关于iOS很奇怪的事情,但我找不到适合我的解决方案.我究竟做错了什么?

Sim*_*ran 6

解决了.感谢@mxcoder让我指向正确的方向.

使用空文件字段创建FormData时,Safari(桌面和iOS)有一个错误.我通过在创建FormData之前禁用空文件字段然后立即重新启用它来解决这个问题,因此在提交Ajax之后可以重用表单.

我改为var data = new FormData(form);:

// Disable empty file fields before submitting.
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
    var $inputs = $('input[type="file"]:not([disabled])', form);
    $inputs.each(function(_, input) {
        if (input.files.length > 0) return
        $(input).prop('disabled', true);
    });
}

var data = new FormData(form);

// Re-enable empty file fields after creating FormData.
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
    $inputs.prop('disabled', false);
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果浏览器是Safari,请禁用空<input type="file">元素
  2. 创建FormData
  3. 如果浏览器是Safari,请重新启用空<input type="file">元素.这允许在成功提交之后或在纠正错误之后重用表单.