tags:

views:

586

answers:

2

Hello, I have a problem with an async call using jquery (ajax, load, get, post). While I wait for the remote site to answer I can't navigate my links until the remote web site either answers or times out.

If I click a link to an external web site (google for example) the page switches right away. I've tried this on my local IIS, windows 2008 IIS7 and the web server that comes with VS2008.

To reproduce copy the following code and change the proxy page to one of your own and make it wait for a long time (or you might want to try the following web service as it takes forever to answer: http://www.webservicex.net/globalweather.asmx/GetWeather?CityName=Inuvik&CountryName=Canada). You'll need to use a proxypage because you can't make remote ajax calls).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
        <title>Test</title>
        <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                //GetRemotePage();
                AjaxRemotePage();
                //LoadRemotePage();
                //PostRemotePage();
            });

            function LoadRemotePage() {
                $("#RemoteDetail").append("Calling delayed page<br />");
                $("#RemoteDetail").load("AjaxProxy.aspx?t/AjaxDelay.aspx?d=10");
            }

            function AjaxRemotePage() {
                $("#RemoteDetail").append("Calling delayed page<br />");
                $.ajax({
                    url: "AjaxProxy.aspx?/AjaxDelay.aspx?d=10",
                    async: true,
                    cache: false,
                    global: false,
                    success: function(html) {
                        $("#RemoteDetail").append("AjaxRemotePage<br />");
                        $("#RemoteDetail").append(html);
                    }
                });
            };

            function PostRemotePage() {
                $("#RemoteDetail").append("Calling delayed page<br />");
                $.post("AjaxProxy.aspx?/AjaxDelay.aspx?d=10", {}, function(xml) {
                    $("#RemoteDetail").append("---In Ajax Call<br />");
                });
            };

            function GetRemotePage() {
                $("#RemoteDetail").append("Calling delayed page<br />");
                $.get("AjaxProxy.aspx?/AjaxDelay.aspx?d=10", {}, function(xml) {
                    $("#RemoteDetail").append("---In Ajax Call<br />");
                });
            }
        </script>

    </head>
    <body>
        <div>
            <a href="http://www.google.com"&gt;go google</a><br />
            <a href="/AjaxTest.htm">go this page</a><br />
            <a href="/">go home page</a><br />
        </div>
        <div id="RemoteDetail">
        </div>
    </body>
</html>

AjaxProxy.aspx => is a proxy paeg that is used to return the response of the rmote page AjaxDelay.aspx => is the simulated remote service/page with an added delay of 10 seconds (d=10) to simulate a very slow remote site/service

Edit: Added AjaxProxy content and AjaxDelay content (both pages are in asp.net 2.0 with nothing in the aspx page)

AjaxProxy

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Request.QueryString.Count = 0 Then Response.Write(" ") : Exit Sub

    Dim Url As String = HttpUtility.UrlDecode(Request.QueryString().ToString)
    Dim req As HttpWebRequest = WebRequest.Create(Url)
    Dim res As HttpWebResponse = req.GetResponse
    Dim sreader As StreamReader = New StreamReader(res.GetResponseStream)
    Dim myhtml As String = sreader.ReadToEnd
    sreader.Close()
    res.Close()
    If Url.EndsWith(".xml") Then
        Response.AddHeader("Content-type", "application/xml")
    End If
    Response.Write(myhtml)
End Sub

AjaxDelay

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim Del As Integer = 2
    If String.IsNullOrEmpty(Request("d")) = False Then
        Integer.TryParse(Request("d"), Del)
        If Del = 0 Then Del = 2
    End If

    Del = Del * 1000
    Threading.Thread.Sleep(Del)
    Response.Write(String.Format("Delayed for {0} seconds", Del / 1000))
End Sub
A: 

Well if the Server that contains the Proxy is located on the local machine that is also making the ajax requests it could be possible that the proxy is doing something to halt the computer processing itself. Have you looked for deficiencies in the proxy code that could cause major blocking?

When you say

windows 2008 IIS7

Is that on a remote machine or is that the local OS/IIS?

Just an additional.. That webservice call returns extremely fast for me.

Edit:
I could not duplicate this with FF3, Chrome, IE6/7 I tried with the following code, it didn't matter what I put in as a substitute url.

<script type="text/javascript">
     $(document).ready(function() {
      //GetRemotePage();
      AjaxRemotePage();
      //LoadRemotePage();
      //PostRemotePage();
     });

     function AjaxRemotePage() {
      $("#RemoteDetail").append("Calling delayed page<br />");
      $.ajax({
      url: "PageProxy.ashx?d=10&externalURI=http://www.yahoo.com",
       async: true,
       cache: false,
       global: false,
       success: function(html) {
        $("#RemoteDetail").append("AjaxRemotePage<br />");
        $("#RemoteDetail").append(html);
       }
      });
     };
</script>

Proxy:

using System;
using System.Web;

public class PageProxy : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
      if (context.Request.QueryString["d"] != null)
       System.Threading.Thread.Sleep(10000);

      byte[] externalPage = new System.Net.WebClient().DownloadData(context.Request["externalURI"]);
      context.Response.OutputStream.Write(externalPage, 0, externalPage.Length);
      context.Response.End();
    }

    public bool IsReusable {
        get {
            return false;
        }
    }
}
Quintin Robinson
Win2008 IIS 7 is the server of my hosting provider (remote)As for the service, must be my location vs yours or perhaps just the few times you tested ;) I tested while I answered and YSlow gave me the following 2 response times, 3 secs and 95secs.
Chuck
I've edited my post to show you the AjaxDelay and AjaxProxy
Chuck
A: 

This works fine for me in Firefox 3.1 and IE8. I replaced the URL with a ColdFusion page that takes 15 seconds to render. I changed the "go this page" link to:

<a href="test2.html">go this page</a><br />

And actually created that file (empty).

Chase Seibert
Forgot to mention I'm using Firefox 3.06You're right I tried IE7, IE6, Chrome and they all changed page immediately, but my Firefox's not moving an inch
Chuck
Scratch that Ie7's not moving either... starting to think that my sleep call's not good
Chuck