简体   繁体   English

单击浏览器上的“停止”按钮会怎样?

[英]What happens when I click the Stop button on the browser?

Let's say I click a button on a web page to initiate a submit request. 假设我单击网页上的按钮以发起提交请求。 Then I suddenly realize that some data I have provided is wrong and that if it gets submitted, then I will face unwanted consequences (something like a shopping request where I may be forced to pay up for this incorrect request). 然后,我突然意识到我提供的某些数据是错误的,并且如果提交了这些数据,那么我将面临不必要的后果(例如购物请求,可能会迫使我支付不正确的请求费用)。

So I frantically click the Stop button not just once but many times (just in case). 因此,我疯狂地单击“停止”按钮不仅是一次,而是多次(以防万一)。

What happens in such a scenario? 在这种情况下会发生什么? Does the browser just cancel the request without informing the server? 浏览器是否只是在不通知服务器的情况下取消了请求? If in case it does inform the server, does the server just kill the process or does it also do some rolling back of all actions done as part of this request? 如果确实通知服务器,则服务器只是终止该进程还是对作为该请求一部分而执行的所有操作进行一些回滚?

I code in Java. 我用Java编写代码。 Does Java have any special feature that we can use to detect STOP requests and rollback whatever we did as part of this transaction? Java是否有任何特殊功能可用于检测STOP请求并回滚在此事务中所做的一切?

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 服务器可用时,浏览器发送HTTP请求
  2. Server executes code (for dynamic pages) 服务器执行代码(用于动态页面)
  3. Server sends the HTTP Response (usually HTML) 服务器发送HTTP响应(通常为HTML)
  4. Browser renders HTML, and asks for other files (images, css, ...) 浏览器呈现HTML,并要求其他文件(图像,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. 如果您的服务器速度慢或过载,并且在步骤1中单击“停止”,则不会发生任何事情。 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). 但是,在大多数情况下,第2、3和4步将被“停止”,在这些步骤中,您的代码已经执行,浏览器只是停止等待响应(2)或接收响应(3)。 ,或呈现响应(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 HTTP调用本身始终是一个两步操作(请求/响应),并且没有自动方式从客户端回滚执行

Since this question may attract attention for people not using Java, I thought I would mention PHPs behavior in regard to this question, since it is very surprising. 由于此问题可能会吸引那些不使用Java的人的注意,因此我想就此问题提及PHP的行为,因为这非常令人惊讶。

PHP internally maintains a status of the connection to the client. PHP在内部维护到客户端的连接状态。 The possible values are NORMAL, ABORTED and TIMEOUT. 可能的值为NORMAL,ABORTED和TIMEOUT。 While the connection status is NORMAL, life is good and the script will continue to execute as expected. 在连接状态为NORMAL的情况下,运行状况良好,脚本将继续按预期执行。

If the user clicks the Stop button in their browser, the connection is typically closed by the client and the status changes to ABORTED. 如果用户单击浏览器中的“停止”按钮,则客户端通常会关闭连接,并且状态将更改为“已暂停”。 A change of status to ABORTED will immediately end execution of the running script. 将状态更改为ABORTED将立即终止正在运行的脚本的执行。 As an aside, the same thing happens when the status changes to TIMEOUT (PHPs setting for the allowed run-time of scripts is exceeded). 顺便说一句,当状态更改为TIMEOUT时,也会发生相同的事情(超过了脚本允许的运行时的PHPs设置)。

This behavior may be useful in certain circumstances, but there are others where it could be problematic. 此行为在某些情况下可能有用,但在其他情况下可能会出现问题。 It seems that it should be safe to abort at any time during a proper GET request; 似乎在适当的GET请求期间随时中止是安全的; however, aborting in the middle of a request that makes a change on the server could lead to only partially completed changes. 但是,在对服务器进行更改的请求中间中止可能导致仅部分完成更改。

Check out the PHP manual's entry on Connection Handling to see how to avoid complications resulting from this behavior: 在连接处理方面查看PHP手册中的条目,以了解如何避免此行为引起的复杂性:

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

Generally speaking, the server will not know that you've hit stop, and the server-side process will complete. 一般来说,服务器不会知道您已经停止运行,并且服务器端过程将完成。 At the point that the server tries to send the response data back to the client, you may see an error because the connection was closed, but equally you may not. 在服务器尝试将响应数据发送回客户端时,您可能会看到错误,因为连接已关闭,但同样地,您可能没有看到。 What you won't get is the server thread being suddenly interrupted. 您将无法获得的是服务器线程突然被中断。

You can use various elaborate mechanisms to mitigate this, like having the send send frequent ajax calls to the server that say "still waiting", and have the server perform its processing in a new thread which checks these calls, but that doesn't solve the problem completely. 您可以使用各种复杂的机制来减轻这种情况,例如让send向服务器发送频繁的ajax调用,说“还在等待”,并让服务器在检查这些调用的新线程中执行其处理,但这不能解决问题。问题完全。

The client will immediately stop transmitting data and close its connection. 客户端将立即停止传输数据并关闭其连接。 9 out of 10 times your request will already have got through (perhaps due to OS buffers being "flushed" to the server). 您的请求中有10个中有9个已经通过(可能是由于OS缓冲区“掉入”了服务器)。 No extra information is sent to the server informing it that you stopped your request. 没有额外的信息发送到服务器,通知它您已停止请求。

Your submit in important scenarios should have two stages. 您在重要方案中的提交应分为两个阶段。 Verify and submit. 验证并提交。 If the final submit goes though, you commit any tranactions. 如果最终提交成功,则您进行任何事务。 I cant think of any other way really to avoid that situation, other than allowing your user to undo his actions after a commit. 除了允许您的用户在提交后撤消其操作之外,我无法想到其他任何方法来真正避免这种情况。 for example The order example, after the order is done to allow your customers to change their mind and canel the order if it has not been shipped yet. 例如订单示例,在完成订单后,您的客户可以改变主意并取消订单(如果尚未发货)。 Of course its extra code you need to write to suuport that. 当然,您需要编写额外的代码来支持suuport。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM