如何处理超时POST请求 [英] How to deal with timed out POST requests

查看:936
本文介绍了如何处理超时POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在RESTful SOA中,假设我通过AJAX发出POST请求,但在请求超时之前我没有得到响应。进一步假设重新提交请求将是有害的。 POST不是幂等的。例如,也许我正在发布银行转帐。如果我没有收到回复,我不知道服务器是否处理了请求。

In a RESTful SOA, suppose I issue a POST request via AJAX but I don't get a response before the request times out. Further suppose a re-submission of the request would be harmful. POST is not idempotent. For example, maybe I am posting a bank transfer of money. If I don't get a response, I don't know if the server processed the request.

假设我有控制权,处理此问题的最佳做法是什么在客户端和服务端?

What is the best practice to deal with this, assuming I have control over the client-side and the services side?

我最初的想法是在每个POST请求中包含一个nonce(即一个伪id;某种唯一标识符) ;例如也许是If-None-Match标头中的值。使用这种方法,客户端可以以编程方式重新发出具有相同伪id的超时请求,如果服务器包含重复值,服务器可以拒绝它。

My initial thought is to include a nonce (i.e. a pseudo-id; some sort of unique identifier) with each POST request; e.g. perhaps a value in the If-None-Match header. With this approach, the client-side can programmatically re-issue a timed out request with the same pseudo-id and the server can reject it if it contains a repeat value.

推荐答案

我听说有很多方法可以解决这个问题

There are a number of ways I've heard of to try to solve this


  1. 获取当前状态。

  1. Get the current state.

设计服务,以便在POST失败时,客户端可以在同一资源上发出GET,并根据返回的数据,可以确定POST是否成功。

Design the service so that if a POST fails, the client can issue a GET on the same resource and based on the data returned, they can determine if the POST was successful of not.

这种方法的问题是在POST在集合中创建新项目的情况下,可能很难客户确定帖子是否成功(即,我的帖子是否添加该项目或做了别人的?)

The problem with this approach is in cases where the POST creates a new item in a collection, it could be difficult for the client to determine if the post was successful or not (i.e., did my post add that item or did someone else's?)

If-Match

使用 If-Match 标头来阻止重复POST。例如,如果POST正在向集合添加项目,并且该集合当前具有 ETag 737060cd8c284d8af7ad3082f209582d 。如果在POST上使用 If-Match 737060cd8c284d8af7ad3082f209582d ,那么POST只有在集合的<$ c时才会成功$ c> ETag 仍然 737060cd8c284d8af7ad3082f209582d ,这将添加项目并产生一个新的 ETag 收集。在这个阶段重复POST只会返回 412 Precondition Failed

Use the If-Match header to prevent the POST from being repeated. e.g., if the POST is adding an item to a collection, and the collection currently has a ETag of 737060cd8c284d8af7ad3082f209582d. If If-Match of 737060cd8c284d8af7ad3082f209582d is used on the POST, then the POST will only succeed if the collection's ETag is still 737060cd8c284d8af7ad3082f209582d, which will add the item and result in a new ETag for the collection. Repeating the POST at this stage will just return 412 Precondition Failed.

这种方法的问题在于你何时出现问题得到 412前提条件失败,你无法确定你的POST是否修改了该集合或其他人的。

The problem with this approach is the when you get a 412 Precondition Failed, you can't be sure if your POST modified the collection or someone else's.

POST然后PUT

POST then PUT

将服务设计为永不保留POST中的数据。而是POST创建一个具有POST内容的临时资源,该内容处于待处理状态。然后,使用PUT提交此临时资源。使用这种方法,你不关心你的POST时间,只是再次请求POST,这次你希望得到你的临时资源。如果PUT提交资源时间,你也不在乎,因为PUT是幂等的。

Design your service to never persist data from a POST. Instead the POST creates a temporary resource with the POST content, which is in a "Pending" state. This temporary resource is then "committed" with a PUT. With this approach you don't care if your POST time's out, just request the POST again and this time you'll hopefully get your temporary resource. If the PUT to commit the resource time's out, you don't care either, because the PUT is idempotent.

这种方法唯一真正的缺点是需要额外的工作管理临时资源和客户所需的额外工作。

The only real downside of this approach is the extra work required to manage the temporary resources and the extra effort required in the client.

更新

Nonce

在请求中使用nonce(也就是消息ID,事务ID,请求ID,关联ID)是解决此问题的常用方法问题;但它可能存在可扩展性问题。
如果您承诺拒绝所有使用先前nonce的POST,则需要扫描现有的POST记录以确定之前是否已使用过nonce。当你只有几千个POST时没有问题,但是当你有数百万的时候它会成为问题(特别是如果你没有以一种快速查询的方式存储nonce)。

The use of a nonce (a.k.a Message ID, Transaction ID, Request ID, Correlation ID) in the request is a common approach for solving this problem; however it can have scalability issues. If you commit to rejecting all POSTs that use a previous nonce, you then need to scan the existing POST records to determine if the nonce has been used before. Not a problem when you have only a few thousand POSTs, but it can become problematic when you have millions (especially if you haven't stored the nonces in a way that is fast to query).

您可以通过减少拒绝在特定时间范围内(例如,过去24小时)使用先前现时的所有POST的承诺来缓解此问题,但如果第一个POST超时且客户端在该时间范围内断开连接,那么他们又回到了原来的位置,他们不知道第一次POST是否成功,也无法确定他们是否应该重新发布。

You can mitigate this by reducing your commitment to rejecting all POSTs that use a previous nonce within a certain timeframe (e.g., last 24hrs), but if the first POST times out and the client is disconnected for that timeframe, then they are back in the same old position, where they don't know if the first POST was successful and have no way to determine if they should rePOST or not.

这篇关于如何处理超时POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆