javascript - jQuery 在等待 ajax 完成时显示服务器实时响应文本

标签 javascript jquery ajax codeigniter

我正在尝试创建一个函数来显示服务器响应,同时等待 ajax 完成,情况是这样的:

  1. 我勾选了几个复选框,假设是 10 个复选框
  2. 点击提交按钮并触发ajax
  3. 在服务器端,有一个循环来执行复选框中的每个值,每个循环可能需要很长时间(现在将有 10 次循环迭代)
  4. 现在在等待 ajax 完成时,我想从服务器获取响应(通过循环编号),例如 Getting data 1 of 10, (total) details obtained...<
  5. ajax完成后,服务器返回'操作成功,重定向到结果页面'

目前只有 4 号除外,我目前的做法是:

  1. 我在 CI 中创建了 2 个函数,函数 A 循环执行操作,函数 B 显示函数 A 中设置的消息
  2. 我创建了 2 个 ajax 函数,ajax X 和 ajax Y。X 用于从 B 获取 json 响应,而 Y 用于提交表单并将其发送给 A。
  3. 我首先使用 setInterval 1 秒调用 ajax X,这有效 仅一次,因为一旦我启动它,它就会被 ajax Y 覆盖。当我尝试在新选项卡中打开函数 B 时(ajax 仍在运行时),它只是加载并且仅在函数 A/ajax 完成后显示消息。幸运的是,在 Chrome 中,我在尝试打开功能 B 时收到了这条消息:Waiting for active connection

那么我该如何实现呢?因为我的客户不是基于 IT 的,所以我想显示一些进度文本,以便他知道正在处理多少数据。

顺便说一下,目前我只使用加载 GIF 并在 ajax 完成时隐藏它。

非常感谢任何帮助或线索,谢谢。

最佳答案

制作两个函数不是一个好主意,因为 A() 和 B() 即使在同一台服务器上并行运行也不能共享它们的变量。您可以只用一个函数和一些巧妙地使用缓冲来存档该结果。我添加了 sleep 匹配耗时的代码。

<?php

set_time_limit(0); 
ob_implicit_flush(true);
ob_end_flush();
session_write_close(); // prevents session lockdowns
for($i = 0; $i < 10; $i++){
    sleep(1);   //Hard work!! zZZ
    $p = $i+1;
    echo  $p . ' of 10 complete ';  //get sent immediately
}

sleep(1);
echo '10 of 10 complete';

注意 ob_implicit_flush(true); implicit flush意味着一旦你回显它就会立即发送到浏览器而不会中断你的连接所以你将在每次循环迭代中从同一个 HTTP 连接中得到 1,2,3.../p>

接下来是 javascript 唯一需要注意的一点是 onreadystatechange 不仅在状态更改时被调用,而且在每个响应从服务器到达时被调用

var xhr = new XMLHttpRequest();  
var prevResponse = '';                   
xhr.onreadystatechange = function() {
    if (this.readyState == 4){
        //stuff you want to do when ajax completes   
        alert('Done!')
    }
    else if (this.readyState > 2){
        var newResponse = this.responseText.substring(prevResponse.length);      
        document.getElementById("status").innerText = newResponse;
        prevResponse = this.responseText;
    }                     
};
xhr.open("GET", "ajax.php", true);
xhr.send();      

还有一点,responseText 属性本质上是缓冲,即。如果您从您的服务器发送“A”xhr.responseText 将给出“A”但现在如果您发送“B”xhr.responseText 将不会是“B”但是而不是 'AB' 这就是为什么我使用 prevResponse 来保存最后的响应,这样我就可以从当前的 responseText 中减去它来只得到这次服务器发送给我的内容。你可以甚至更进一步,让它成为一个进度条,只需让服务器在 JSON 中发送百分比,在客户端对其进行解码,将 value 应用于进度条,并使用一些很酷的 CSS 效果就可以了。

对于 $.ajax 试试这个

$.ajax({
  url:'ajax.php',
  xhr: function(){ 
        var prevResponse = '';   
        var req = $.ajaxSettings.xhr();
        req.onreadystatechange = function() {
            if (this.readyState == 4){
              //stuff you want to do when ajax completes   
            }
            else if (this.readyState > 2){
              var newResponse = this.responseText.substring(prevResponse.length);      
              document.getElementById("status").innerText = newResponse;
              prevResponse = this.responseText;
            }
        }             
        return req;
  }
  //other options
});

关于javascript - jQuery 在等待 ajax 完成时显示服务器实时响应文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41420026/

相关文章:

Javascript 内存游戏拼图

javascript - 使用 JS 将类应用于父元素

javascript - IronRouter 获取布局中的数据

javascript - Morris.js 条形图是否更改了条形宽度?

javascript - 删除 ng-repeat 而不会泄漏

c# - 增加 ASP.NET 页面方法的最大响应大小

javascript - 如何用末尾没有空白的div水平填充页面

javascript 自执行语法

javascript - 当异步设置为 true 时,JAVAFX Ajax 调用偶尔无法添加到请求正文

javascript - 为什么将元素追加到末尾