Javascript 关闭页面后脚本会继续运行吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5997102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Will a script continue to run even after closing a page?
提问by Francesco
if i call a php file via jquery ajax, that contains a script to do some stuff that takes a while — for instance uploading a big video — and then I close the page: does the php script keep loading the video or not?
如果我通过 jquery ajax 调用一个 php 文件,它包含一个脚本来做一些需要一段时间的事情——例如上传一个大视频——然后我关闭页面:php脚本是否继续加载视频?
采纳答案by M?rre
See here: http://php.net/manual/en/function.ignore-user-abort.php
见这里:http: //php.net/manual/en/function.ignore-user-abort.php
int ignore_user_abort ([ bool $value ] )
Sets whether a client disconnect should cause a script to be aborted.
When running PHP as a command line script, and the script's tty goes away without the script being terminated then the script will die the next time it tries to write anything, unless value is set to TRUE
int ignore_user_abort ([ bool $value ] )
设置客户端断开连接是否应导致脚本中止。
当 PHP 作为命令行脚本运行时,脚本的 tty 消失而脚本没有终止,那么脚本将在下次尝试写入任何内容时死亡,除非将值设置为 TRUE
There also is a PHP configuration option of the same name: http://php.net/manual/en/misc.configuration.php
还有一个同名的 PHP 配置选项:http: //php.net/manual/en/misc.configuration.php
By default, if you do nothing, according to the PHP manual the default is to abort the script. http://php.net/manual/en/features.connection-handling.php
默认情况下,如果你什么都不做,根据 PHP 手册默认是中止脚本。 http://php.net/manual/en/features.connection-handling.php
NECESSARY UPDATE
必要的更新
It seems I (unknowingly) tricked my way to "reputation points", because I did NOT supply the (correct) answer, but here it is now thanks to testing and continued nudging from "mellamokb":
看来我(不知不觉地)欺骗了我的“声誉点”,因为我没有提供(正确的)答案,但现在要感谢测试并继续从“ mellamokb”中轻推:
Quote: "Ok, I took a look at the PHP source code and, if I didn't miss anything, I now have the answer. The "ignore_user_abort" flag is only checked when PHP receive an error trying to output something to the user. So, in my understanding, there is no way to interrupt code which doesn't produce any output."
引用:“好的,我查看了 PHP 源代码,如果我没有遗漏任何内容,我现在有了答案。仅当 PHP 收到尝试向用户输出某些内容的错误时才会检查“ignore_user_abort”标志. 所以,在我的理解中,没有办法中断不产生任何输出的代码。”
Okay, I wasn't totally off, but it is important to know that it all depends on whether or not your script produced any output!
好吧,我并没有完全离开,但重要的是要知道这一切都取决于您的脚本是否产生了任何输出!
If you read THIS, also DO check out the comments below.
如果你阅读了这篇文章,也请查看下面的评论。
回答by zzarbi
A PHP Script running through a web server will not stop until:
通过 Web 服务器运行的 PHP 脚本不会停止,直到:
- someone kill the server
- the server kill the php scrip
- 有人杀死服务器
- 服务器杀死 php 脚本
When the user abort the script, PHP will continue until it try to send something back to the browser.
当用户中止脚本时,PHP 将继续运行,直到它尝试将某些内容发送回浏览器。
For example still script will continue fore ever even if the user abort:
例如,即使用户中止,仍然脚本将永远继续:
while(true){
echo 'go'.PHP_EOL;
}
It will go on forever because the "echo", will write into the buffer, and the buffer will not be sent to the browser until the script finish, which will never happen.
它将永远持续下去,因为“回声”将写入缓冲区,并且在脚本完成之前缓冲区不会发送到浏览器,这永远不会发生。
The following script will stop as soon as the user abort:
一旦用户中止,以下脚本将停止:
while(true){
echo 'go'.PHP_EOL;
flush();
ob_flush();
}
This script will stop, because flush() and ob_flush() will force PHP to send its buffer to the browser, which will stop the PHP script if the user has aborted. The function ignore-user-abort() will force PHP to ignore the abort in this case.
该脚本将停止,因为 flush() 和 ob_flush() 将强制 PHP 将其缓冲区发送到浏览器,如果用户中止,它将停止 PHP 脚本。在这种情况下,函数 ignore-user-abort() 将强制 PHP 忽略中止。
Moreover if you are using PHP session, they are another tricky situation. For example, if you are doing AJAX, and you actually send two AJAX request to a PHP script and that PHP script has need of session with session_start(). The first AJAX query will work normally, however the second one will have to wait until the first call is finish, because the first script has a locked on the session. The first script could eventually prematurely release the session with session_write_close();
此外,如果您使用的是 PHP 会话,则它们是另一种棘手的情况。例如,如果您正在执行 AJAX,并且您实际上向 PHP 脚本发送了两个 AJAX 请求,并且该 PHP 脚本需要使用 session_start() 进行会话。第一个 AJAX 查询将正常工作,但是第二个将必须等到第一个调用完成,因为第一个脚本已锁定会话。第一个脚本最终可能会使用 session_write_close() 过早地释放会话;
回答by Tadeck
By default no. See Connection Handlingdocumentation, especially:
默认没有。请参阅连接处理文档,尤其是:
You can decide whether or not you want a client disconnect to cause your script to be aborted. Sometimes it is handy to always have your scripts run to completion even if there is no remote browser receiving the output. The default behaviour is however for your script to be aborted when the remote client disconnects.
您可以决定是否希望客户端断开连接导致脚本中止。有时即使没有远程浏览器接收输出,始终让脚本运行完成也很方便。但是,默认行为是在远程客户端断开连接时中止您的脚本。
回答by Repky
The script will run the time set by max_execution_time (default is 30s)
脚本将运行由 max_execution_time 设置的时间(默认为 30s)
WarningThis function has no effect when PHP is running in safe mode. There is no workaround other than turning off safe mode or changing the time limit in the php.ini. Note: The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real. quote from http://php.net/manual/en/function.set-time-limit.php
警告当 PHP 在安全模式下运行时,此功能无效。除了关闭安全模式或更改 php.ini 中的时间限制外,没有其他解决方法。 注意: set_time_limit() 函数和配置指令 max_execution_time 只影响脚本本身的执行时间。在确定脚本运行的最长时间时,不包括在脚本执行之外发生的活动(例如使用 system() 的系统调用、流操作、数据库查询等)上花费的任何时间。在测量时间是真实的 Windows 上,情况并非如此。 引自http://php.net/manual/en/function.set-time-limit.php
you can test this by running
你可以通过运行来测试这个
<?php
unlink('cocorico.txt');
while(true){
file_put_contents('cocorico.txt', microtime(true).PHP_EOL, FILE_APPEND);
}
and it will stop after 30s (despite you close your browser or not)
you can get you default exec time by echo ini_get('max_execution_time');
and can be set like set_time_limit(3);
The answer marked as accepted is only correct about the ignore_user_abort
but don't panic that your "fail" scripts will run forever if you don't set max exec time to 0 - unlimited;
它会在 30 秒后停止(无论您是否关闭浏览器),您可以获得默认的执行时间,echo ini_get('max_execution_time');
并且可以设置set_time_limit(3);
为 标记为已接受的答案仅是正确的,ignore_user_abort
但不要惊慌您的“失败”脚本将如果您未将最大执行时间设置为 0,则永远运行 - 无限制;
回答by Delta
From my little understanding of how these stuff works. By the point of view of the HTTP protocol I would say yes, the script would keep running, because the browser just sends a request to the server asking for the page, then the server starts executing the script and does not sends or receives information from the browser untill the script is done loading and producing the html output, and just then the server sends the resulting output to the browser and has done the job.
从我对这些东西如何工作的一点了解来看。从 HTTP 协议的角度来看,我会说是的,脚本会继续运行,因为浏览器只是向服务器发送请求页面的请求,然后服务器开始执行脚本并且不发送或接收来自浏览器,直到脚本完成加载和生成 html 输出,然后服务器将结果输出发送到浏览器并完成工作。
See, there is no way for a browser to "tell" the server that the user is not viewing the page anymore through the HTTP protocol. However, the HTTP protocol runs on top of the TCP connection through stream sockets, the TCP connection is kept alive till one of the ends choses to abort the connection (or a certain timeout is reached), now I really don't know how the browser handles this. The browser could just open a connection, send a request and close the connection, then the server waits for the script and sends the response on another connection. Or the browser could open a connection, KEEP this connection alive till the server responds on the same connection. If the thing works that way then the server would really have a way to know if the user is not viewing the page anymore simply by checking if the connection is still alive or has been shutdown by the client. So that would be a no.
看,浏览器无法通过 HTTP 协议“告诉”服务器用户不再查看页面。但是,HTTP 协议通过流套接字运行在 TCP 连接之上,TCP 连接一直保持活动状态,直到其中一端选择中止连接(或达到某个超时),现在我真的不知道如何浏览器处理这个。浏览器可以只打开一个连接,发送请求并关闭连接,然后服务器等待脚本并在另一个连接上发送响应。或者浏览器可以打开一个连接,保持这个连接处于活动状态,直到服务器响应同一个连接。如果事情以这种方式工作,那么服务器真的有办法知道用户是否不再查看页面,只需检查连接是否仍然有效或已被客户端关闭。所以那将是一个不。
Dunno much about that tho.
不知道太多关于那个寿。