IFRAME中的PHP脚本阻止其他代码

时间:2013-10-30 19:36:03

标签: javascript php ajax iframe wamp

情景:

我有两个PHP脚本可以同时调用:

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

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

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

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

    • PHP Version 5.4.12
    • Apache / 2.4.4(Win64)PHP / 5.4.12
    • Windows 7 x64
    • 8GB RAM
    • Google Chrome版本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> 中的脚本 Scripts execution order

1 个答案:

答案 0 :(得分:3)

你的问题很简单,你可以想象。你只是没有意识到它可能有点缺乏HTML的知识。所以你的代码还可以,一切都按你的意愿运行,但应该同时运行的脚本不是,问题是什么?

<body onload="callScripts();">

这就是你的问题。仅当onload标记内的所有内容都已完全加载时,body调用才会发生。因此,当您的iframe位于body html解释器中时,加载所有内容(包括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>

让我知道它之后是否有用