AJAX PHP脚本输出的连续响应

如何解决AJAX PHP脚本输出的连续响应

我的PHP脚本的AJAX响应有问题...

我创建了“ Status” div,我想在其中输出PHP脚本的响应。它运作良好,但是只有在整个脚本完成后才显示响应,我想输出每个“实时”回显。.

这是我的文件:

form.php

<!-- left column -->
<div class="col-md-6">
    <!-- general form elements -->
    <div class="card card-primary">
        <div class="card-header">
            <h3 class="card-title"><?php echo $xmlData->name ?></h3>
        </div>
        <!-- /.card-header -->
        <!-- form start -->
        <form id="upload_form" enctype="multipart/form-data" method="post">
            <div class="card-body">
                <div class="form-group">
                    <label for="debFile">Deb file</label>
                    <span id="debMSG"></span>
                    <div class="input-group">
                        <div class="custom-file">
                            <input name="debFile" type="file" class="custom-file-input" id="debFile">
                            <label class="custom-file-label" for="debFile">Choose .deb file</label>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <label for="version">Version</label>
                    <input type="text" name="version" id="version" class="form-control" value="<?php echo ver_up($xmlData->changelogs->change->version); ?>">
                </div>
                <div class="form-group">
                    <label for="log">Log</label>
                    <input type="text" name="log" id="log" class="form-control" value="Bug fix">
                </div>
                <div class="form-check">
                    <input name="tweet" type="checkbox" class="form-check-input" id="tweet" value="1">
                    <label class="form-check-label" for="tweet">Auto-post on Twitter</label>
                </div>
            </div>
            <!-- /.card-body -->

            <div class="card-footer">
                <button id="submit" name="upload" type="submit" class="btn btn-primary">Update</button>
            </div>
        </form>
    </div>
    <!-- /.card -->
</div>
<!-- Status -->
<div id="status" class="col-md-6" style="display:none;">
    <div class="card card-default">
        <div class="card-header">
            <h3 class="card-title">Status:</h3>
        </div>
        <div class="alert alert-default">
            <ul id="output" class="list-group"></ul>
        </div>
    </div>
</div>
<!--/.col (right) -->

form.php中的ajax

<script type="text/javascript">
$(document).ready(function () {
    bsCustomFileInput.init();

    const Toast = Swal.mixin({
        toast: true,position: 'top-end',showConfirmButton: false,timer: 5000
    });

    $(document).on('submit','#upload_form',function(event){
        event.preventDefault();

        if($('#debFile').val() == '')
        {
            $('#debMSG').html('<div class="alert alert-danger">Enter .deb file!</div>');
            $('#debMSG').show();
            setTimeout(function() {
                $('#debMSG').fadeOut('fast');
            },5000);
            return false;
        }
        else
        {

            $.ajax({
                type: 'POST',url: 'scripts/test.php',data: new FormData(this),// async: true,cache: false,processData: false,contentType: false,beforeSend:function()
                {
                    $('#debMSG').hide();
                    $('#submit').attr('disabled','disabled');
                    // $('#status').fadeIn('slow');
                }
            })
            .done(function(data) {
                // console.log(data);
                $('#output').append(data);
                $('#status').fadeIn('slow');
                // if(!data.success){
                //  $('#submit').removeClass('btn-primary').addClass('btn-danger');
                //  $('#submit').attr('disabled',false);
                //  $('#submit').removeAttr('name type');
                //  $('#submit').attr('onClick','location.reload();');
                //  $('#submit').html('Reload');
                //  Toast.fire({
                //      icon: 'error',//      title: 'There was an error while updating tweak!'
                //  })
                // } else {
                    $('#submit').removeClass('btn-primary').addClass('btn-success');
                    $('#submit').attr('disabled',false);
                    $('#submit').removeAttr('name type');
                    $('#submit').attr('onClick','window.location.href = "manage-packages.php";');
                    $('#submit').html('Finish');
                    Toast.fire({
                        icon: 'success',title: 'Tweak has been successfully updated!'
                    })
                // }
            })
            .fail(function(data) {
                console.log(data);
                $('#output').append("There was an error while updating tweak!");
                // $('#output').removeClass('alert-success').addClass('alert-danger');
                $('#status').fadeIn('slow');
                $('#submit').removeClass('btn-primary').addClass('btn-danger');
                $('#submit').attr('disabled',false);
                $('#submit').removeAttr('name type');
                $('#submit').attr('onClick','location.reload();');
                $('#submit').html('Reload');
                Toast.fire({
                    icon: 'error',title: 'There was an error while updating tweak!'
                })
            });
        }
    });
});
</script>

test.php

<?php

header('Content-type: text/html; charset=utf-8');

require_once("../../src/config-ssh.php");
require_once("../../src/functions.php");

$deb_dir = "/var/www/html/debs/";
$repo_dir = "/var/www/html/";

function output($val) {
    echo nl2br ($val);
    flush();
    ob_flush();
    sleep(1);
}

try {
    if (isset($_FILES["debFile"]["name"])) {
        $debFile = $_FILES["debFile"]["tmp_name"];
        $deb_file = $deb_dir . basename($_FILES["debFile"]["name"]);

        if (!file_exists($deb_file)) {
            output("<li class=\"list-group-item list-group-item-success\">DEB file \"". basename( $_FILES["debFile"]["name"]). "\" has been uploaded.</li>");
        } else {
            throw new Exception("<li class=\"list-group-item list-group-item-danger\">DEB file \"". basename( $_FILES["debFile"]["name"]). "\" already exists!</li>");
        }
    } else {
        throw new Exception("<li class=\"list-group-item list-group-item-danger\">You didn't choose any DEB file!</li>");
    }

    preg_match('/(.*)_(.*)_(.*)\.deb/',basename($_FILES["debFile"]["name"]),$deb_reg);
    $dirname = $deb_reg[1];
    $prev_ver = ver_down($deb_reg[2]);
    $exten = $deb_reg[3] . ".deb";
    $prev_deb_name = $dirname."_".$prev_ver."_".$exten;
    $prev_deb = $deb_dir . $prev_deb_name;

    if (isset($_POST['version']) && isset($_POST['log'])) {
        output("<li class=\"list-group-item list-group-item-success\">Values were added to XML!</li>");
    }

    if (file_exists($prev_deb)) {
        output("<li class=\"list-group-item list-group-item-success\">Previous version of DEB file (\"". $prev_deb_name . "\") was deleted!</li>");
    } else {
        throw new Exception("<li class=\"list-group-item list-group-item-danger\">DEB file \"". $prev_deb_name . "\" wasn't deleted!</li>");
    }


    // Run a command
    output("<li class=\"list-group-item list-group-item-info\">Running Repo update script...</li>");
        output("<li class=\"list-group-item list-group-item-success\">Script finished successfully.</li>");

    // Auto-post Tweet
    if (isset($_POST['tweet'])) {
        output("$msg");
        output("<li class=\"list-group-item list-group-item-success\">Tweet has been successfully posted.</li>");
    }

    exit();
}

catch( Exception $e ) {
    $message = $e->getMessage();

    die( "ERROR: " . $message );
}

?>

最后,它输出以下状态输出:

enter image description here

我已经尝试过一些教程,但是没有一个正在为此工作...

感谢您的建议!

解决方法

您需要将处理程序绑定到XmlHttpRequest对象的progress事件。 jQuery不提供执行此操作的本机接口,但是如果您仍想使用jQuery而不是直接使用XmlHttpRequest对象来进行AJAX调用,则可以使用xhr回调函数来更改基础XmlHttpRequest对象,并添加处理程序这样:

$.ajax({
    ...
    xhr: function() {
        // get the native XmlHttpRequest object
        const xhr = $.ajaxSettings.xhr();
        // set the onprogress event handler
        xhr.onprogress = function() {
            // replace the '#output' element inner HTML with the received part of the response
            $('#output').html(xhr.responseText);
        }
        return xhr;
    }
})
.done(function(data) {
    ...
})
.fail(function(data) {
    ...
});

很难从XMLHttpRequest标准的current version中弄清楚,但是archived one说此事件大约每50毫秒或接收到的每个字节触发一次,以频率最低的那个为准。>

您应该对JavaScript代码进行的其他更改是

  • 取消注释$('#status').fadeIn('slow');函数中的beforeSend行并将其从其他函数中删除;
  • $('#output').append(data);事件处理函数中删除done行,应该已经通过onprogress处理函数注入了所有接收到的数据。

最后但并非最不重要的部分是关于缓冲。我假定您将nginx与PHP-FPM结合使用,因为您将nginx标记添加到了问题中。您已经使用了flush()ob_flush() PHP函数,并且正确的是,您需要同时使用这两个函数才能刷新PHP缓冲区。但是,还有另外一种缓冲机制-nginx本身。您可以使用fastcgi_buffering off;指令完全关闭nginx FastCGI缓冲,但这似乎不是一个好主意。幸运的是,nginx允许通过特殊的X-Accel-Buffering标头关闭响应缓冲,因此您的AJAX PHP处理程序应以

开头
<?php

header('Content-type: text/html; charset=utf-8');
header('X-Accel-Buffering: no');

...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-