如何安全地重试失败的jQuery ajax POST请求?

如何安全地重试失败的jQuery ajax POST请求?,jquery,ajax,rest,post,idempotent,Jquery,Ajax,Rest,Post,Idempotent,在RESTful体系结构中,POST请求既不安全也不幂等 现在,jQuery的ajax调用允许重试失败的请求,方法是将ajax调用设置为使用error函数捕获失败,并可选地重试调用(以及相关设置,如超时,tryCount,retryAfter和retryLimit) 重试GET调用不是问题(因为它们都是安全的且幂等的),但如何重试POST调用呢 例如,假设我们使用ajax POST插入新记录: 在客户端上启动ajax POST调用 该调用由服务器接收,服务器更新数据库 服务器响应,但此响应无法传

在RESTful体系结构中,POST请求既不安全也不幂等

现在,jQuery的ajax调用允许重试失败的请求,方法是将ajax调用设置为使用
error
函数捕获失败,并可选地重试调用(以及相关设置,如
超时
tryCount
retryAfter
retryLimit

重试GET调用不是问题(因为它们都是安全的且幂等的),但如何重试POST调用呢

例如,假设我们使用ajax POST插入新记录:

  • 在客户端上启动ajax POST调用
  • 该调用由服务器接收,服务器更新数据库
  • 服务器响应,但此响应无法传递到客户端
  • 因此,客户端假定出现了故障,并重试该调用
  • 服务器会再次接收该呼叫,从而进行另一个更改
  • 等等

  • 满足这种情况的最佳方法是什么?

    您的代码可以轻松使用的唯一方法(请原谅双关语)是确认数据已被接收和接受

    所以答案实际上取决于帖子的性质。如果帖子确实是一个更新,比如将name设置为“John”,那么您可以安全地重试几次,直到得到确认

    然而,您所讨论的情况是,一篇文章实际上是REST意义上的一篇文章,这意味着它将添加一个新行。在这种情况下,正确的方法取决于客户机和服务器之间更深入的握手

    最后,数据完整性是处理数据库的代码的工作,服务器代码也是如此。因此,如果不应复制行,则场景将按如下方式进行:

    • 客户端对“提交令牌”进行GET,包括客户端生成的ID
    • 服务器基于clientID生成提交令牌,并将其存储在表中
    • 服务器将令牌发送到客户端
    • 客户端提交包含令牌的POST
    • 服务器接收令牌,验证令牌,插入post,并成功响应

    • 因此,如果GET令牌请求没有发送到服务器,客户端可以再次请求,始终使用相同的clientID
    • 如果客户端最终得到一个令牌,他可以假设服务器有他的请求的记录,并期待后续的帖子
    • 如果客户端在几次失败后得到多个令牌响应,那么它们都将是相同的令牌
    • 因此,客户机将发布并继续发布(使用令牌),直到收到成功
    • 如果服务器收到其中一个POST,它将插入数据并使令牌无效,并成功响应
    • 如果服务器曾经收到请求并且已经使用了令牌,它将以“重复请求”响应
    • 客户机只能收到1个“成功”,如果客户机碰巧没有收到,那么在以后的尝试中,它将收到“重复请求”,并且知道它已插入
    现在,如果服务器不关心重复项,而您无法控制它,而它只是客户机,那么最好的解决方案就是在重试之前等待很长时间,并且始终交替使用get和post。理论上你永远不会知道,因为也许他们有一个队列,在服务器离线时收集请求,下周他们会处理它们