2

设想:

我有两个要同时调用的 PHP 脚本:

  1. 第一个脚本将运行几分钟(基于 PHP 的文件下载),具体取决于下载的文件大小
  2. 第二个 PHP 脚本应该定期调用以监控第一个脚本的执行 - 文件进度下载。为了避免在脚本完成时打开新窗口,它通过 AJAX 调用。

问题:

在执行第一个长时间运行的 PHP(稍后下载)脚本期间,不会处理定期调用的 AJAX 监控脚本。只有当第一个脚本完成时,才会处理名为 PHP 的 AJAX 脚本。

我花了很多时间解决这个问题。我已经尽可能地简化了我的测试脚本。但是,在执行主 php 脚本期间,我仍然无法让 AJAX 脚本正常工作。我也不能以任何其他方式从主下载脚本中获取中间反馈值。

请您好心分析一下我的代码示例好吗?它们具有我现在使用的精确形式。如果可能的话,你会这么好心并在你的环境中运行它们吗?我怀疑问题可能出在我的 WAMP 环境中。

  • PHP 版本 5.4.12
  • Apache/2.4.4 (Win64) PHP/5.4.12
  • 视窗 7 x64
  • 8GB 内存

代码示例:

调用两个 PHP 脚本的 JavaScript 代码:

<!DOCTYPE html>
<html>
<head>
    <title>Title of the document</title>
</head>

<body onload="callScripts();">


<script type="text/javascript">

    // call both PHP scripts(download and monitoring) in desired order
    callScripts = function()
    {
        // run long running (later Download) PHP script
        console.log("Calling: PHP/fileDownload.php");
        window.location.href = 'PHP/fileDownload.php';

        // call the monitoring PHP script multiple times in 2 second intervals
        window.setTimeout(function(){startDownloadMonitoring()}, 1000);
        window.setTimeout(function(){startDownloadMonitoring()}, 3000);
        window.setTimeout(function(){startDownloadMonitoring()}, 5000);
        window.setTimeout(function(){startDownloadMonitoring()}, 7000);
        window.setTimeout(function(){startDownloadMonitoring()}, 9000);
    };


    // call monitoring PHP script via AJAX
    function startDownloadMonitoring()
    {
        console.log("Calling startDownloadMonitoring()...");

        var xmlhttp;

        if (window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.onreadystatechange = function()
        {
            if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {
                console.log("Response Received: " + xmlhttp.responseText);
            }
        }
        xmlhttp.open("GET", "PHP/fileDownloadStatus.php", true);
        xmlhttp.send();
    }
</script>
</body>
</html>

PHP 监控脚本(fileDownloadStatus.php)

<?php

include 'ChromePhp.php';

// start session, update session variable, close session
session_start();
$_SESSION['DownloadProgress']++;
ChromePhp::log('$_SESSION[\'DownloadProgress\'] = ' . $_SESSION['DownloadProgress']);
session_write_close();    

echo "success";
?>

PHP 长时间运行脚本 (fileDownload.php)

<?php
include 'ChromePhp.php';

// disable script expiry
set_time_limit(0);

// start session, define variable, close session
session_start();

// prepare session variables
$_SESSION['DownloadProgress'] = 10;

session_write_close();

// execute for 60 seconds    
for( $count = 0; $count < 60; $count++)
{
    sleep(1);
}

?>
4

2 回答 2

3

它不是通过 ajax 发送的第一个脚本:

 // run long running (later Download) PHP script
  console.log("Calling: PHP/fileDownload.php");
  window.location.href = 'PHP/fileDownload.php';

您只需将用户重定向到另一个页面,并且因为您download headers在 php 中,该文件被下载到同一页面中。

您可以通过iframe. 您设置该 iframe 的来源:'PHP/fileDownload.php'然后只需调用您的 ajax 下载检查器。

简短的例子:

<iframe src="PHP/fileDownload.php">

<script>
        window.setTimeout(function(){startDownloadMonitoring()}, 1000);
        window.setTimeout(function(){startDownloadMonitoring()}, 3000);
        window.setTimeout(function(){startDownloadMonitoring()}, 5000);
        window.setTimeout(function(){startDownloadMonitoring()}, 7000);
        window.setTimeout(function(){startDownloadMonitoring()}, 9000);
        // .... blah blah
</script>
于 2013-10-30T13:16:07.093 回答
1

你打电话时

    window.location.href = 'PHP/fileDownload.php';

脚本执行停止(不是立即停止,请参阅https://stackoverflow.com/a/2536815/2806497)。

你确定执行了对 fileDownloadStatus.php 的 ajax 调用吗?

一种解决方案是通过 ajax 异步调用来调用 fileDownloadStatus.php 文件,或者将其加载到您放入页面的 iframe 中。

希望有帮助。

于 2013-10-30T13:23:06.267 回答