在执行WebRequest时显示加载文本

时间:2022-12-04 20:33:35

I have a button on my webform. Clicking this button will do an HttpWebRequest during the onclick event handler. After the request we copy the response from the request into HttpContext.Current.Response and send that to the client.

我的网络表单上有一个按钮。单击此按钮将在onclick事件处理程序期间执行HttpWebRequest。在请求之后,我们将请求中的响应复制到HttpContext.Current.Response并将其发送到客户端。

This web request can take a while (up to 5 seconds, since it's generating a report). During this time the user has no indication that anything is going on, except for the browser progress bar and the spinning IE icon (if they're using IE). So I need a loading indicator while this is happening.

此Web请求可能需要一段时间(最多5秒,因为它正在生成报告)。在此期间,除了浏览器进度条和旋转IE图标(如果他们使用IE)之外,用户没有任何指示正在进行任何操作。所以当发生这种情况时我需要一个加载指示器。

I've tried using javascript that fires during the button's onclick event (using OnClientClick) and while that works, I don't know how to find out when the web request is finished. Since we just send the response to the client, a full postback doesn't happen.

我尝试使用在按钮的onclick事件期间触发的javascript(使用OnClientClick),虽然这有效,但我不知道如何找出Web请求何时完成。由于我们只是将响应发送给客户端,因此不会发生完整的回发。

I've tried wrapping the button in an UpdatePanel and using the UpdateProgress, but when we send the response to HttpContext.Current.Response and call Response.End(), we get an error in the javascript, since the response isn't well formed (we're sending back an excel sheet for the user to download).

我已经尝试在UpdatePanel中包装按钮并使用UpdateProgress,但是当我们将响应发送到HttpContext.Current.Response并调用Response.End()时,我们在javascript中收到错误,因为响应不太好形成(我们发回一张excel表供用户下载)。

Since we're sending back a file for users to download, I don't want to pop-up a separate window, since then in IE they'd get the information bar blocking the download.

由于我们要发回一个供用户下载的文件,我不想弹出一个单独的窗口,因为在IE中他们会得到阻止下载的信息栏。

Any ideas here?

这里有什么想法?

4 个解决方案

#1


4  

As an alternative to the Professional AJAX.NET library, jQuery has a really nice way of doing this.

作为Professional AJAX.NET库的替代品,jQuery有一个非常好的方法。

Take a look at this example of using a .NET PageMethod (if possible in your scenario).

看看这个使用.NET PageMethod的示例(如果可能,在您的场景中)。

You define a page method call in jQuery, you can tack on your loading... message in a hidden div.

你在jQuery中定义一个页面方法调用,你可以在隐藏的div中添加你的loading ...消息。

Say what callback you want to return on success (ie when your 5 second report is generated) then hide the loading and handle the data.

说出您想要在成功时返回的回调(即生成5秒报告时),然后隐藏加载并处理数据。

Take a look at the javascript on my contact page for an example (view the source).

请查看我的联系页面上的javascript以获取示例(查看源代码)。

  1. I have a a button on the page, add the jQuery onClick.
  2. 我在页面上有一个按钮,添加jQuery onClick。

  3. When clicked that shows a hidden loading div, makes an ajax call to a page method that takes the parameters of the form.
  4. 当单击显示隐藏的加载div时,对页面方法进行ajax调用,该方法接受表单的参数。

  5. The page method does emailing etc then returns to the form in the onSuccess javascript method I have there.
  6. 页面方法会发送电子邮件等,然后返回到我在那里的onSuccess javascript方法中的表单。

  7. The onSuccess hides the loading div.
  8. onSuccess隐藏了加载div。

#2


1  

A simple trick i have used in the past is to redirect to an intermediate page with an animated progress bar (gif) and then have that page do the REAL post of the data. (or even pop-up a layer with the animation on it and a polite message asking the user to wait a minute or two)

我过去使用的一个简单技巧是重定向到带有动画进度条(gif)的中间页面,然后让该页面执行数据的REAL帖子。 (甚至弹出一个带有动画的图层和礼貌的消息,要求用户等一两分钟)

The simple feedback of the animated gif creates the illusion to the end user that the app is not stalled and they will be more patient.

动画gif的简单反馈给最终用户带来了错觉,即应用程序没有停滞,他们会更耐心。

Another approach is to hand the data off to a worker thread and return immediately with a message stating that the report will be emailed or made available in the "reports" section of the site when it is ready. This approach lacks the benefit of instant notification when the report is completed though.

另一种方法是将数据移交给工作线程并立即返回,并显示一条消息,指出报告将在网站准备好后通过电子邮件发送或在网站的“报告”部分提供。尽管如此,这种方法在报告完成时缺乏即时通知的好处。

#3


1  

Here is my solution :

这是我的解决方案:

  1. Download and examine the samples of free Professional AJAX.NET library.
  2. 下载并检查免费的Professional AJAX.NET库的示例。

  3. Write a AjaxMethod that creates your file and returns file location as a parameter.
  4. 编写一个AjaxMethod来创建文件并将文件位置作为参数返回。

  5. Write your Client-Side function to call method at Step 2. When this method called show an indicator.
  6. 将您的客户端函数写入步骤2中的调用方法。此方法调用时显示指示符。

  7. Write a client-side callback method to hide indicator and show/download file that user requested.
  8. 编写客户端回调方法来隐藏指标和显示/下载用户请求的文件。

  9. Add your client-side function calls yo your button element.
  10. 添加您的客户端函数调用您的按钮元素。

When your method at server-side ends your callback will be called.

当您的服务器端方法结束时,将调用您的回调。

Hope this helps !

希望这可以帮助 !

#4


0  

The solution I'm presenting here is aimed to show a method to let a "Loading..." box to appear while you're server-side processing and to disappear when server-side processing is complete.

我在这里介绍的解决方案旨在展示一种方法,让您在服务器端处理时出现“正在加载...”框,并在服务器端处理完成时消失。

I'll do this with the very basic AJAX machinery (tested on FF, but IE should be ok either), i.e. not using a framework like Prototype or jQuery or Dojo, as you didn't specify your knowledge about them.

我将使用非常基本的AJAX机制(在FF上测试,但IE也应该没问题),即不使用像Prototype或jQuery或Dojo这样的框架,因为你没有指定你对它们的了解。

To let you better understand the trick, the following is just a small example and doesn't pretend to be an out-of-the-box solution. I tend not to be superficial, but I think a clearer example can explain better than many words.

为了让您更好地理解这个技巧,以下只是一个小例子,并不假装是一个开箱即用的解决方案。我倾向于不肤浅,但我认为一个更清晰的例子可以比许多词语更好地解释。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>First Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
            .hidden {
                display: none;
            }
            .loadingInProgress {
                color: #FFFFFF;
                width: 75px;
                background-color: #FF0000;
            }
        </style>
    <script type="text/javascript">
        var httpRequest;
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            httpRequest = new XMLHttpRequest();
            httpRequest.overrideMimeType('text/xml');
        } else if (window.ActiveXObject) { // IE
            try {
                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch (e) {
                try {
                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                }
                catch (e) {}
            }
        }

        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
        }

        httpRequest.onreadystatechange = function(){
            switch (httpRequest.readyState) {
            case 1: // Loading
                document.getElementById('loading').className = "loadingInProgress";
                break;
            case 4: // Complete
                document.getElementById('loading').className = "hidden";
                if (httpRequest.status == 200) {
                    // perfect!
                } else {
                    // there was a problem with the request,
                    // for example the response may be a 404 (Not Found)
                    // or 500 (Internal Server Error) response codes
                }
                break;
            }
        };

        function go() {
            httpRequest.open('GET', document.getElementById('form1').action, true);
            httpRequest.send('');
        }
    </script>

  </head>
  <body>
      <div id="loading" class="hidden">Loading...</div>
      <form id="form1" name="form1" action="doSomething.php">
          <input type="button" value="Click to submit:" onclick="go()" />
      </form>
  </body>
</html>

As you can see, there's a <div> which holds the "Loading..." message.

如您所见,有一个

,其中包含“正在加载...”消息。

The principle is to show/hide the <div> depending on the XMLHttpRequest object's readyState.

原理是根据XMLHttpRequest对象的readyState显示/隐藏

I've used the onreadystatechange handler of the XMLHttpRequest to trigger the readyState change.

我已经使用XMLHttpRequest的onreadystatechange处理程序来触发readyState更改。

The back-end php script I use (declared as the form's action) does just a sleep(5), to let the "Loading..." message appear for 5 secs.

我使用的后端php脚本(声明为表单的动作)只是一个sleep(5),让“Loading ...”消息出现5秒。

<?php
sleep(5);
header('Cache-Control: no-cache');
echo "OK";
?>

The Cache-control: no-cache header is necessary, since usually if you don't set it the browser will cache the response avoiding to resubmit the request if you should need to.

Cache-control:no-cache标头是必需的,因为通常如果你没有设置它,浏览器将缓存响应,避免在需要时重新提交请求。

A good source for "getting started" AJAX documentation is Mozilla MDC.

“入门”AJAX文档的一个很好的来源是Mozilla MDC。

The whole thing could be much more gently handled by a Javascript framework like Prototype, taking advantage of its browser-safe approach, saving you hours of debug.

整个事情可以通过像Prototype这样的Javascript框架轻松处理,利用其浏览器安全的方法,节省您的调试时间。


Edit:

I chose php 'cause I don't know ASP.NET nor ASP, sorry about that.

我选择了php'因为我不知道ASP.NET也不知道ASP,对不起。


#1


4  

As an alternative to the Professional AJAX.NET library, jQuery has a really nice way of doing this.

作为Professional AJAX.NET库的替代品,jQuery有一个非常好的方法。

Take a look at this example of using a .NET PageMethod (if possible in your scenario).

看看这个使用.NET PageMethod的示例(如果可能,在您的场景中)。

You define a page method call in jQuery, you can tack on your loading... message in a hidden div.

你在jQuery中定义一个页面方法调用,你可以在隐藏的div中添加你的loading ...消息。

Say what callback you want to return on success (ie when your 5 second report is generated) then hide the loading and handle the data.

说出您想要在成功时返回的回调(即生成5秒报告时),然后隐藏加载并处理数据。

Take a look at the javascript on my contact page for an example (view the source).

请查看我的联系页面上的javascript以获取示例(查看源代码)。

  1. I have a a button on the page, add the jQuery onClick.
  2. 我在页面上有一个按钮,添加jQuery onClick。

  3. When clicked that shows a hidden loading div, makes an ajax call to a page method that takes the parameters of the form.
  4. 当单击显示隐藏的加载div时,对页面方法进行ajax调用,该方法接受表单的参数。

  5. The page method does emailing etc then returns to the form in the onSuccess javascript method I have there.
  6. 页面方法会发送电子邮件等,然后返回到我在那里的onSuccess javascript方法中的表单。

  7. The onSuccess hides the loading div.
  8. onSuccess隐藏了加载div。

#2


1  

A simple trick i have used in the past is to redirect to an intermediate page with an animated progress bar (gif) and then have that page do the REAL post of the data. (or even pop-up a layer with the animation on it and a polite message asking the user to wait a minute or two)

我过去使用的一个简单技巧是重定向到带有动画进度条(gif)的中间页面,然后让该页面执行数据的REAL帖子。 (甚至弹出一个带有动画的图层和礼貌的消息,要求用户等一两分钟)

The simple feedback of the animated gif creates the illusion to the end user that the app is not stalled and they will be more patient.

动画gif的简单反馈给最终用户带来了错觉,即应用程序没有停滞,他们会更耐心。

Another approach is to hand the data off to a worker thread and return immediately with a message stating that the report will be emailed or made available in the "reports" section of the site when it is ready. This approach lacks the benefit of instant notification when the report is completed though.

另一种方法是将数据移交给工作线程并立即返回,并显示一条消息,指出报告将在网站准备好后通过电子邮件发送或在网站的“报告”部分提供。尽管如此,这种方法在报告完成时缺乏即时通知的好处。

#3


1  

Here is my solution :

这是我的解决方案:

  1. Download and examine the samples of free Professional AJAX.NET library.
  2. 下载并检查免费的Professional AJAX.NET库的示例。

  3. Write a AjaxMethod that creates your file and returns file location as a parameter.
  4. 编写一个AjaxMethod来创建文件并将文件位置作为参数返回。

  5. Write your Client-Side function to call method at Step 2. When this method called show an indicator.
  6. 将您的客户端函数写入步骤2中的调用方法。此方法调用时显示指示符。

  7. Write a client-side callback method to hide indicator and show/download file that user requested.
  8. 编写客户端回调方法来隐藏指标和显示/下载用户请求的文件。

  9. Add your client-side function calls yo your button element.
  10. 添加您的客户端函数调用您的按钮元素。

When your method at server-side ends your callback will be called.

当您的服务器端方法结束时,将调用您的回调。

Hope this helps !

希望这可以帮助 !

#4


0  

The solution I'm presenting here is aimed to show a method to let a "Loading..." box to appear while you're server-side processing and to disappear when server-side processing is complete.

我在这里介绍的解决方案旨在展示一种方法,让您在服务器端处理时出现“正在加载...”框,并在服务器端处理完成时消失。

I'll do this with the very basic AJAX machinery (tested on FF, but IE should be ok either), i.e. not using a framework like Prototype or jQuery or Dojo, as you didn't specify your knowledge about them.

我将使用非常基本的AJAX机制(在FF上测试,但IE也应该没问题),即不使用像Prototype或jQuery或Dojo这样的框架,因为你没有指定你对它们的了解。

To let you better understand the trick, the following is just a small example and doesn't pretend to be an out-of-the-box solution. I tend not to be superficial, but I think a clearer example can explain better than many words.

为了让您更好地理解这个技巧,以下只是一个小例子,并不假装是一个开箱即用的解决方案。我倾向于不肤浅,但我认为一个更清晰的例子可以比许多词语更好地解释。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>First Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
            .hidden {
                display: none;
            }
            .loadingInProgress {
                color: #FFFFFF;
                width: 75px;
                background-color: #FF0000;
            }
        </style>
    <script type="text/javascript">
        var httpRequest;
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            httpRequest = new XMLHttpRequest();
            httpRequest.overrideMimeType('text/xml');
        } else if (window.ActiveXObject) { // IE
            try {
                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch (e) {
                try {
                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                }
                catch (e) {}
            }
        }

        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
        }

        httpRequest.onreadystatechange = function(){
            switch (httpRequest.readyState) {
            case 1: // Loading
                document.getElementById('loading').className = "loadingInProgress";
                break;
            case 4: // Complete
                document.getElementById('loading').className = "hidden";
                if (httpRequest.status == 200) {
                    // perfect!
                } else {
                    // there was a problem with the request,
                    // for example the response may be a 404 (Not Found)
                    // or 500 (Internal Server Error) response codes
                }
                break;
            }
        };

        function go() {
            httpRequest.open('GET', document.getElementById('form1').action, true);
            httpRequest.send('');
        }
    </script>

  </head>
  <body>
      <div id="loading" class="hidden">Loading...</div>
      <form id="form1" name="form1" action="doSomething.php">
          <input type="button" value="Click to submit:" onclick="go()" />
      </form>
  </body>
</html>

As you can see, there's a <div> which holds the "Loading..." message.

如您所见,有一个

,其中包含“正在加载...”消息。

The principle is to show/hide the <div> depending on the XMLHttpRequest object's readyState.

原理是根据XMLHttpRequest对象的readyState显示/隐藏

I've used the onreadystatechange handler of the XMLHttpRequest to trigger the readyState change.

我已经使用XMLHttpRequest的onreadystatechange处理程序来触发readyState更改。

The back-end php script I use (declared as the form's action) does just a sleep(5), to let the "Loading..." message appear for 5 secs.

我使用的后端php脚本(声明为表单的动作)只是一个sleep(5),让“Loading ...”消息出现5秒。

<?php
sleep(5);
header('Cache-Control: no-cache');
echo "OK";
?>

The Cache-control: no-cache header is necessary, since usually if you don't set it the browser will cache the response avoiding to resubmit the request if you should need to.

Cache-control:no-cache标头是必需的,因为通常如果你没有设置它,浏览器将缓存响应,避免在需要时重新提交请求。

A good source for "getting started" AJAX documentation is Mozilla MDC.

“入门”AJAX文档的一个很好的来源是Mozilla MDC。

The whole thing could be much more gently handled by a Javascript framework like Prototype, taking advantage of its browser-safe approach, saving you hours of debug.

整个事情可以通过像Prototype这样的Javascript框架轻松处理,利用其浏览器安全的方法,节省您的调试时间。


Edit:

I chose php 'cause I don't know ASP.NET nor ASP, sorry about that.

我选择了php'因为我不知道ASP.NET也不知道ASP,对不起。


相关文章