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

时间:2022-12-06 09:07:23

Scenario:

I have two PHP scripts to be called simultaneously:

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

  1. The first script will run several minutes (PHP based file download), depending on downloaded file size. It is placed into <iframe> so it can run separately and does not block the browser.
  2. 第一个脚本将运行几分钟(基于PHP的文件下载),具体取决于下载的文件大小。它被放置在

  3. The second PHP script is supposed to be called in regular intervals to monitor execution of the first script - file progress download. To avoid opening new windows upon script completion, it is called via AJAX.
  4. 应该定期调用第二个PHP脚本来监视第一个脚本的执行 - 文件进度下载。为了避免在脚本完成时打开新窗口,可以通过AJAX调用它。

Problem:

I have placed the long-running PHP Script (download script) into <iframe> so this script can run asynchronously with other monitoring PHP script. However, despite the main script is in <iframe>, when the webpage starts execution, the script starts and blocks execution of the remaining JavaScript code and monitoring script called multiple times via AJAX.

我已将长时间运行的PHP脚本(下载脚本)放入

It is important to have the short-running monitoring PHP script called simultaneously with the long-running PHP (download) script, so the short-running (monitoring)script can provide feedback to JavaScript.

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

Would you be so kind and analyze my code samples please? I have no idea, where is my problem. My code is so simple, that everything should be running well.

你会这么善良并分析我的代码样本吗?我不知道,我的问题在哪里。我的代码非常简单,一切都运行良好。

  • PHP Version 5.4.12
  • PHP版本5.4.12

  • Apache/2.4.4 (Win64) PHP/5.4.12
  • Apache / 2.4.4(Win64)PHP / 5.4.12

  • Windows 7 x64
  • Windows 7 x64

  • 8GB RAM
  • Google Chrome Version 30.0.1599.101 m
  • 谷歌浏览器版本30.0.1599.101米

Code Samples:

JavaScript code calling both PHP scripts:

调用两个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 Monitoring Script(fileDownloadStatus.php)

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 long-running script (fileDownload.php)

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();
}
?>

Screenshot:

PHP Scripts Execution Order - browser waits to finish the script in <iframe> IFRAME中的PHP脚本阻止其他代码

PHP脚本执行顺序 - 浏览器等待在

1 个解决方案

#1


3  

Your problem is as simple as you can imagine. You just don't realize it maybe for a bit lack of knowledge of HTML. So Your code is ok and everything is working as you want but the script that should run at the same time isn't, what is the problem?

你的问题就像你想象的那样简单。你只是没有意识到它可能有点缺乏HTML的知识。所以你的代码是好的,一切都按你的要求工作但是应该同时运行的脚本不是,问题是什么?

<body onload="callScripts();">

This up here is your problem. The onload call only takes place when everything inside the body tag is completely loaded. So, as your iframe is inside the body the html interpreter load everything (including the iframe and its source), then call your callScripts function.

这就是你的问题。 onload调用仅在body标记内的所有内容完全加载时发生。因此,当您的iframe位于正文中时,html解释器会加载所有内容(包括iframe及其源代码),然后调用您的callScripts函数。

To solve your problem I recommend you to create your iframe inside your script. Would be something as this:

要解决您的问题,我建议您在脚本中创建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>

Let me know if it work after that

让我知道它之后是否有用

#1


3  

Your problem is as simple as you can imagine. You just don't realize it maybe for a bit lack of knowledge of HTML. So Your code is ok and everything is working as you want but the script that should run at the same time isn't, what is the problem?

你的问题就像你想象的那样简单。你只是没有意识到它可能有点缺乏HTML的知识。所以你的代码是好的,一切都按你的要求工作但是应该同时运行的脚本不是,问题是什么?

<body onload="callScripts();">

This up here is your problem. The onload call only takes place when everything inside the body tag is completely loaded. So, as your iframe is inside the body the html interpreter load everything (including the iframe and its source), then call your callScripts function.

这就是你的问题。 onload调用仅在body标记内的所有内容完全加载时发生。因此,当您的iframe位于正文中时,html解释器会加载所有内容(包括iframe及其源代码),然后调用您的callScripts函数。

To solve your problem I recommend you to create your iframe inside your script. Would be something as this:

要解决您的问题,我建议您在脚本中创建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>

Let me know if it work after that

让我知道它之后是否有用