26

假设我单击网页上的按钮以发起提交请求。然后我突然意识到我提供的一些数据是错误的,如果它被提交,那么我将面临不必要的后果(比如购物请求,我可能被迫为这个错误的请求付款)。

所以我不只是一次而是多次疯狂地点击停止按钮(以防万一)。

在这种情况下会发生什么?浏览器是否只是取消请求而不通知服务器?如果它确实通知服务器,服务器是否只是终止该进程,或者它是否还对作为该请求的一部分完成的所有操作进行一些回滚?

我用Java编码。Java 是否有任何特殊功能可用于检测 STOP 请求并回滚我们在此事务中所做的任何事情?

4

5 回答 5

22

A Web Page load from a browser is usually a 4 step process (not considering redirections):

  1. Browser sends HTTP Request, when the Server is available
  2. Server executes code (for dynamic pages)
  3. Server sends the HTTP Response (usually HTML)
  4. Browser renders HTML, and asks for other files (images, css, ...)

The browser reaction to "Stop" depends on the step your request is at that time:

  • If your server is slow or overloaded, and you hit "Stop" during step 1, nothing happens. The browser doesn't send the request.
  • Most of the times, however, "Stop" will be hit on steps 2, 3 and 4, and in those steps your code is already executed, the browser simply stops waiting for the response (2), or receiving the response (3), or rendering the response (4).

The HTTP call itself is always a 2 steps action (Request/Response), and there is no automatic way to rollback the execution from the client

于 2008-09-26T07:34:24.033 回答
12

由于这个问题可能会引起不使用 Java 的人的注意,所以我想我会提到 PHP 的行为,因为它非常令人惊讶。

PHP 在内部维护与客户端的连接状态。可能的值为 NORMAL、ABORTED 和 TIMEOUT。虽然连接状态为 NORMAL,但生活还不错,脚本将继续按预期执行。

如果用户在浏览器中单击“停止”按钮,客户端通常会关闭连接,并且状态会更改为 ABORTED。将状态更改为 ABORTED 将立即结束正在运行的脚本的执行。顺便说一句,当状态更改为 TIMEOUT 时会发生同样的事情(超出了脚本允许的运行时间的 PHP 设置)。

这种行为在某些情况下可能有用,但在其他情况下可能会出现问题。似乎在正确的 GET 请求期间随时中止应该是安全的;但是,在对服务器进行更改的请求中间中止可能会导致仅部分完成更改。

查看 PHP 手册中关于连接处理的条目,了解如何避免这种行为导致的并发症:

http://www.php.net/manual/en/features.connection-handling.php

于 2010-03-23T14:47:24.867 回答
3

一般来说,服务器不会知道你点击了停止,然后服务器端的进程就会完成。在服务器尝试将响应数据发送回客户端时,您可能会看到一个错误,因为连接已关闭,但同样您可能不会。你不会得到的是服务器线程突然被中断。

您可以使用各种精心设计的机制来缓解这种情况,例如让 send 向服务器发送频繁的 ajax 调用,说“仍在等待”,并让服务器在检查这些调用的新线程中执行其处理,但这并不能解决问题完全。

于 2008-09-26T07:20:32.053 回答
1

客户端将立即停止传输数据并关闭其连接。十分之九的请求已经通过(可能是由于操作系统缓冲区被“刷新”到服务器)。不会向服务器发送任何额外信息,通知它您停止了请求。

于 2008-09-26T07:22:45.777 回答
0

您在重要场景中的提交应该有两个阶段。验证并提交。如果最终提交成功,您将提交任何交易。除了允许您的用户在提交后撤消他的操作之外,我想不出任何其他方法来真正避免这种情况。例如订单示例,在订单完成后让您的客户改变主意并取消订单(如果尚未发货)。当然,您需要编写额外的代码来支持它。

于 2008-09-26T07:25:25.007 回答