【问题标题】:Are there progress update events in jQuery ajax?jQuery ajax 中是否有进度更新事件?
【发布时间】:2011-02-17 01:34:14
【问题描述】:

我有一个使用 jquery ajax 调用的长时间运行的任务。我正在使用block ui plugin to show“加载”。无论如何我可以将进度消息发送回客户端以显示进度并在块 ui 插件消息上更新。

所以它会显示这一点(随着服务器的工作)。 .

“正在加载第一个源……”
“正在加载第二个来源……”
“正在加载第三个来源……”
“解析结果……”

【问题讨论】:

  • 我的服务器端是 C#,但我认为由于后端语言不同,答案不会有任何差异
  • 答案取决于->“长时间运行的任务”是在客户端还是服务器端执行?
  • 长时间运行的任务在服务器端

标签: jquery asp.net-mvc progress blockui


【解决方案1】:

嗯,我有类似的情况,我用另一种方法解决了它。 这是一个非常丑陋的解决方法,我知道所以请不要开始说它有多糟糕,因为我知道,但它可以满足我的需要。

我将进度放在服务器端的文件中。 例如,我调用了 process.php,它需要做很多工作,并且需要一段时间才能完成,所以用户很紧张,他关闭了浏览器(不太好)。 所以 process.php 正在将一些输出保存到服务器上的文件中。 在调用 process.php 的页面上,我有一个小 div、span 或任何我想显示进度的地方,但我建议使用 div。每 X 毫秒或秒,我从 div 中的服务器加载另一个脚本,比如说 display_info.php 现在 display_info.php 正在读取 process.php 输出的文件,并将内容显示在 div 中。

您必须小心,process.php 的输出对于每个场合都必须是唯一的,否则您会弄乱向浏览器输出的信息。

埃米尔

【讨论】:

    【解决方案2】:

    从我所看到的上传内容的情况来看 - 人们创建了一个单独的网关并查询它以获取进度信息,因为它仅在服务器端可用。但我认为在你的情况下这不是最好的。

    如果您想加载带有进度信息的内容或允许服务器在生成输出时弹出进度信息,那么 http 流媒体 就是您想要的。 here 很好地覆盖了它。基本上它是一个单一的 http 请求,服务器会在一分钟左右的时间内分块响应该请求(因此在需要时发送内容),然后打开一个新连接。

    这对我来说是一个相当大的发现;)

    [编辑]

    目前有很多更好的技术可用,所有这些都包含在Socket.IO - Websockets 中,可以回退到其他技术,包括 http 流

    Socket.IO 是 nodeJS 的一个模块,但还有其他类似的实现。我已经与https://github.com/Atmosphere/atmosphere 的 JAVA Socket.IO 实现交换了一些数据包

    【讨论】:

    • 感谢您指出这一点。我将帖子中使用的资源更改为一些更新的内容。
    【解决方案3】:

    我会让每个 AJAX 请求返回一个 JSON 响应,其中包含一条消息、数据和下一个要请求的 URL:{message: "Loading second resource...", data: ..., next_url: "/next_part"}

    在您的第一个 AJAX 请求之前,将 BlockUI 消息设置为“正在加载...”。当您收到响应时,将 BlockUI 消息设置为您从 AJAX 调用返回的消息。然后对“next_url”的值进行下一次 AJAX 调用,以此类推,循环直到完成所有任务。

    如果您要加载一个大型数据集,但要分段加载,您可能需要执行progressive loading design pattern 之类的操作,但还要在收到每个响应时设置进度消息。

    【讨论】:

      【解决方案4】:

      您正在尝试做的事情类似于Comet。传统(“非彗星”)网络服务器不是为这种交易模型设计的,因此不是理想的解决方案。

      我的建议是将每个数据源的处理分解为一个客户端请求:

      function loadData() {
         // Each call passes callback(id) as a success handler
         fireAsynchronousRequest("source1");
         fireAsynchronousRequest("source2");
         fireAsynchronousRequest("source3");
      }
      
      function callback(var source) {
         if (source == "source1") {
             updateStatus("Source 1 loaded");
         }
         else if (source == "source2") {
             updateStatus("Source 2 loaded");
         }
      }
      

      这是一个异步解决方案的示例。如果需要同步,可以在callback() 中实现状态处理。

      【讨论】:

        【解决方案5】:

        一种方法是在 jQuery 中使用 HTTP 处理程序和 AJAX。

        1.发起服务器端请求

        $("#btnCreateInvoice").click(function() {             
               $.ajax({ type: "POST",  url: "YourHttpHandler.ashx",
               contentType: "text/html; charset=utf-8",
               dataType: "html",  
               success: function(data) { start the block UI }
               });
            });
        

        2。投票

        接下来您需要做的是在 't' 间隔轮询服务器并获取状态。为此,我们需要以 't' 间隔调用一个函数,该函数将启动对 HTTPHandler 的 AJAX 调用以获取状态。

        $(function() {
          setInterval(updateStatus, 't');
        });
        
        function updateStatus() {
          $.ajax({ type: "POST",  url: "GetStatusHandler.ashx",
               contentType: "text/html; charset=utf-8",
               dataType: "html",  
               success: function(data) { process 'data' here and update the block UI message box }
               });
        }
        

        在您的情况下,GetStatusHandler.ashx 可以返回完整的 innerHtml 状态。 例如,在第一次调用时,它将返回“正在加载第一个源...”,然后它可能会返回:
        正在寻找第一个来源...
        正在加载第二个来源...
        等等。

        【讨论】:

          【解决方案6】:

          我最近才意识到一个执行 ajax “推送”的项目。您可能想检查一下:

          http://www.ape-project.org/

          据我所知,还有一些其他项目在做类似的事情,这是最真实的:“将进度消息发送回客户端”,其中另一个解决方案需要请求轮询进度(仍然是一个非常合法且良好的解决方案)。

          【讨论】:

          • 这个项目使用 http 流,并在我提供的第二个链接中链接。尽管如此,ape-project 是一个用于 http 流的 c++ 服务器,使用它来做一个进度条对我来说似乎有点过头了。
          猜你喜欢
          • 2012-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-23
          • 1970-01-01
          • 2012-12-08
          • 1970-01-01
          相关资源
          最近更新 更多