处理来自多个表单输入的多个AJax发布失败

时间:2018-12-27 01:32:18

标签: javascript jquery ajax

我正在开发一个PHP应用程序,用于处理多项选择和基于文本的问题。在Javascript代码中,当用户回答问题时,ajax提交将响应提交到PHP服务器。

这是它的工作方式:

$('textarea,input').on('change',function postinput() {
  var name = $(this).attr('name');
  var value = $(this).val();
  var itemstr = name + "=" + value;
  $.ajax({
    url: window.location.href,
    data: itemstr,
    type: 'post'
  }).done(function(responseData) {
    console.log('Done: ', responseData);
  }).fail(function() {
    console.log('Failed');
  });
});

目前,它完全可以按预期完成工作。服务器获取响应,并将其存储在数据库中。

但是,我的解决方案的AJax部分需要更加强大。如果用户去回答问题时出现暂时性的网络故障该怎么办?甚至更糟的是,如果网络中断一两分钟甚至更长的时间,该怎么办?或者,如果服务器出现故障怎么办?我需要让用户知道存在问题,然后自动重试,或者给他们一个按钮以按下以重试。

处理Ajax代码中这些错误的最佳方法是什么?答案当然是填写“ fail”块,但我不确定那应该是什么样。

由于每次表单更改都会启动Ajax响应,因此我不希望它们中的每一个都单独重试,否则它可能会在备份时加载服务器。失败块如何跟踪所有提交中失败的提交,并定期重试?

1 个答案:

答案 0 :(得分:0)

从失败中,我们可以收集一些东西

  1. 状态码
  2. 状态文本(失败原因)

我们可以生成一个唯一密钥,并将其用作失败ID。这可能有效:

function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

现在,当请求失败时,我们可以将失败推送到队列中。

$.ajax({
    …
  }).done(function(responseData) {
    …
  }).fail(function(data) {
    const { statusText, status } = data;
    addToFailureQueue({
      requestId: guid(),
      failureText: statusText,
      statusCode: status
    });
  });

使用setInterval函数,您可以进行轮询,以检查队列是否为空。如果没有,您可以遍历并重新初始化每个失败的请求。重新初始化的请求成功后,将其从队列中删除。

这里是demo入门。该演示不包括轮询,但会收集失败的请求。

let failureQueue = [];

// Generates a unique string of characters suitable for a key
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

function showOutput(obj) {
  const output = $('.output');
	for (let o in obj) {
    if (obj.hasOwnProperty(o)) {
    	output.append(`<li><strong>${o}</strong>: ${obj[o]}</li>`) 
    }
  }
}

function addToFailureQueue(obj) {
	failureQueue.push(obj);
  showOutput(obj);
} 

function makeFakeRequest() {
  $.ajax({
    url: window.location.href,
    data: '',
    type: 'post'
  }).done(function(responseData) {
    console.log('Done: ', responseData);
  }).fail(function(data) {
    const { statusText, status } = data;
    addToFailureQueue({
      requestId: guid(),
    	failureText: statusText,
      statusCode: status
    });
  });
}

$('.myButton').on('click', makeFakeRequest);
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

.output {
  background-color: #fff;
}

.output:not(:empty) {
  padding: 1rem;
}

.output li {
  margin: 0;
  padding: 0 0 .5rem;
  list-style: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<button class="myButton">Make fake request</button>
<ul class="output"></ul>