3

设想:

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

  1. 第一个脚本将运行几分钟(基于 PHP 的文件下载),具体取决于下载的文件大小。它被放入<iframe>以便它可以单独运行并且不会阻止浏览器。
  2. 第二个 PHP 脚本应该定期调用以监视第一个脚本的执行 - 文件进度下载。为了避免在脚本完成时打开新窗口,它通过 AJAX 调用。

问题:

我已将长时间运行的 PHP 脚本(下载脚本)放入<iframe>其中,以便该脚本可以与其他监控 PHP 脚本异步运行。然而,尽管主脚本在 中<iframe>,但当网页开始执行时,该脚本会启动并阻止执行剩余的 JavaScript 代码和通过 AJAX 多次调用的监控脚本。

让短期运行的监控 PHP 脚本与长期运行的 PHP(下载)脚本同时调用很重要,因此短期运行(监控)脚本可以向 JavaScript 提供反馈。

请您好心分析一下我的代码示例好吗?我不知道,我的问题在哪里。我的代码非常简单,一切都应该运行良好。

  • PHP 版本 5.4.12
  • Apache/2.4.4 (Win64) PHP/5.4.12
  • 视窗 7 x64
  • 8GB 内存
  • 谷歌浏览器版本 30.0.1599.101 m

代码示例:

调用两个 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()
    {
        // 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>

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

</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 if session is not already started
session_start();

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

session_write_close();

for( $count = 0; $count < 60; $count++)
{
    sleep(1);

    print("fileDownload Script was called: ". $count);

    echo "Download script: " . $count;
    ob_flush();
    flush();
}
?>

截屏:

PHP 脚本执行顺序 - 浏览器等待完成脚本<iframe> 脚本执行顺序

4

1 回答 1

3

你的问题和你想象的一样简单。您只是没有意识到这可能是因为对 HTML 有点缺乏了解。所以你的代码没问题,一切都按照你的意愿工作,但是应该同时运行的脚本不是,有什么问题?

<body onload="callScripts();">

这是你的问题。onload仅当body标签内的所有内容都已完全加载时,才会进行调用。因此,当您iframebodyhtml 解释器中加载所有内容(包括 iframe 及其源代码)时,然后调用您的callScripts函数。

为了解决您的问题,我建议您iframe在脚本内部创建。会是这样的:

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

    <!-- You should always define your script in the head tag. best pratice
     defined in W3C -->

<script type="text/javascript">

    callScripts = function (){
         //write your Iframe Here
         document.getElementById("callDownload").innerHTML = '<iframe src="PHP/fileDownload.php"></iframe>'; 
         callScripts_refresh();
    }

    // call both PHP scripts(download and monitoring) in desired order
    callScripts_refresh = function()
    {

        // 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>

</head>

<body onload="callScripts();">

<div id="callDownload"></div>

</body>
</html>

让我知道它是否在那之后工作

于 2013-10-31T02:20:05.013 回答