SitePoint Sponsor

User Tag List

Results 1 to 24 of 24
  1. #1
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    AJAX, not sending POST parameters to server

    Hey, i've been reading simple javascript from sitepoint, very good.

    Been playing around with the AJAX script for submitting a form, but it's playing up... I've finally figured out what's going wrong, it's not passing the POST data to the server. I've checked the post parameters are right (submitby=ajax&text=hellofihwseghsli&group=2&order=-&action=update%20section&sid=14&current_group=2&current_order=1&name=gets%20boring).

    I'm displaying the returned data and in that returned data i have dumped the entire $_POST variable... So it show list every single variable within the POST array, but it comes back as empty.

    Code JavaScript:
    var ContactForm =
    {
    	init: function()
    	{
    		var allforms = Core.getElementsByClass("AJAXupdatable");
    		for (var i = 0, l = allforms.length; i < l; i++)
    		{
    			Core.addEventListener(allforms[i], "submit", ContactForm.submitListener);
    		}
    	},
    	submitListener: function(event)
    	{
    		var form = this;
     
    		try
    		{
    			var requester = new XMLHttpRequest();
    		}
    		catch (error)
    		{
    			try
    			{
    				var requester = new ActiveXObject("Microsoft.XMLHTTP");
    			}
    			catch (error)
    			{
    				var requester = null;
    			}
    		}
     
    		if (requester != null)
    		{
    			form._timer = setTimeout(function()
    					{
    						requester.abort();
    						ContactForm.writeError("The server timed out while making your request.");
    					}, 10000);
     
    			var parameters = "submitby=ajax";
    			var formElements = [];
     
    			var textareas = form.getElementsByTagName("textarea");
     
    			for (var i = 0; i < textareas.length; i++)
    			{
    				formElements[formElements.length] = textareas[i];
    			}
     
    			var selects = form.getElementsByTagName("select");
     
    			for (var i = 0; i < selects.length; i++)
    			{
    				formElements[formElements.length] = selects[i];
    			}
     
    			var inputs = form.getElementsByTagName("input");
     
    			for (var i = 0; i < inputs.length; i++)
    			{
    				var inputType = inputs[i].getAttribute("type");
     
    				if (inputType == null || inputType == "text" || inputType == "hidden" || (typeof inputs[i].checked != "undefined" && inputs[i].checked == true))
    				{
    					formElements[formElements.length] = inputs[i];
    				}
    			}
     
    			for (var i = 0; i < formElements.length; i++)
    			{
    				var elementName = formElements[i].getAttribute("name");
     
    				if (elementName != null && elementName != "")
    				{
    					parameters += "&" + elementName + "=" + encodeURIComponent(formElements[i].value);
    				}
    			}
     
    			requester.open("POST", form.getAttribute("action")+"&xml=true", true);
    			requester.onreadystatechange = function()
    			{
    				clearTimeout(form._timer);
     
    				if (requester.readyState == 4)
    				{
    					if (requester.status == 200 || requester.status == 304)
    					{
    						ContactForm.writeSuccess(requester.responseText);
    					}
    					else
    					{
    						ContactForm.writeError("The server was unable to be contacted.");
    					}
    				}
    			};
     
    			var newP = document.getElementById("messages");
    			newP.innerHTML = parameters;
    			requester.send(parameters);
    			Core.preventDefault(event);
    		}
    	},
    	writeSuccess: function(data)
    	{
    		var newP = document.getElementById("messages");
    		newP.innerHTML = newP.innerHTML+data;
     
    	},
    	writeError: function(errorMsg)
    	{
    		alert(errorMsg);
    	}
    };
     
    Core.start(ContactForm);

    Returned data:

    HTML Code:
    <pre>bool(true)
    </pre>
    <pre>array(0) {
    }</pre>
    <pre>array(3) {
      ["p"]=&gt;
      string(7) "profile"
      ["f"]=&gt;
      string(13) "updateSection"
      ["xml"]=&gt;
    
      string(4) "true"
    }</pre>
    The first bit is the dump of a variable called xml, it just checks if $_GET['xml'] exists and if it's true, that way it'll show XML instead of HTML. It's true, which is as it should be.
    the second bit is the $_POST array... As you can see, it's empty.
    The third bit is the $_GET array, as it should be.

    Really not sure what's wrong. Knowing my luck it'll be something small i'll have over looked =/
    Any help is appreciated ! : )

  2. #2
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wow, 11 views and no comments :P

    I've edited the original one to see if that sends the POST data...But that doesn't either... I thought the whole point of the script was to send the post data =/

    Why don't either of them work ?

  3. #3
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry, I think I clicked on this 11 times and got lazy every time. That's a lot of code to sink in. You might want to abstract out an asyncRequest function so you'll have less spaghetti to deal with. Here is one that I wrote a while back.

    Code:
    var asyncRequest = function() {
      function handleReadyState(o, callback) {
        if (o && o.readyState == 4 && o.status == 200) {
          if (callback) {
            callback(o);
          }
        }
      }
      var getXHR = function() {
        var http;
        try {
          http = new XMLHttpRequest;
            getXHR = function() {
              return new XMLHttpRequest;
            };
        }
        catch(e) {
          var msxml = [
            ‘MSXML2.XMLHTTP.3.0′,
            ‘MSXML2.XMLHTTP’,
            ‘Microsoft.XMLHTTP’
          ];
          for (var i=0, len = msxml.length; i < len; ++i) {
            try {
              http = new ActiveXObject(msxml[i]);
              getXHR = function() {
                return new ActiveXObject(msxml[i]);
              };
              break;
            }
            catch(e) {}
          }
        }
        return http;
      };
      return function(method, uri, callback, postData) {
        var http = getXHR();
        http.open(method, uri, true);
        handleReadyState(http, callback);
        http.send(postData || null);
        return http;
      };
    }();
    That should give you support to do this:

    Code:
    asyncRequest('POST', 'test.php', callback, 'foo=bar&baz=thunk');
    function callback(o) {
      alert(o.responseText);
    }
    Code:
    <?php
    // test.php
    echo $_POST['foo'];
    ?>

  4. #4
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I managed to get it to work by adding...


    requester.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    requester.setRequestHeader("Content-length", parameters.length);

    But i think i'll implement that anyway ^___^ Seeing as it's much more reusable :P Thanks

    One thing though, handleReadyState... It checks if it returns 200, but isn't there 304 (successful but the file hasn't been modified since it was last downloaded - so it uses browser cache instead) as well ? Or do browsers not cache when it comes to httprequest's ?

  5. #5
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Browser -do- cache (xmlHTTPRequests). So, you're correct on that point. 304 is a valid status code. But if you're doing ajax in a sense where you're 'requesting' information, it doesn't do much good if that information is cached (and always returning back the same information). Nevertheless, some people leave that extra check out, some people leave it in. It's up to you

  6. #6
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is there anyway of forcing the browser to give the wrong details (like it downloaded the file afew years ago, which is gonna make the server send a 200 instead (well, if it's been updated in the last few years ;P) ?).

  7. #7
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you could always append a datestamp string to the end of your uri parameter. That will force a new request...

    Code:
    var uri = 'test.php?stamp=' + new Date;
    asyncRequest('POST', uri, callback, postParams);
    But, you want the -wrong- details?

  8. #8
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah good thinking with the date thing ;P

    No, with the wrong details thing i meant fake that it hasn't downloaded that file recently even it has.

    I've made afew changes to it to meet my needs...
    Code JavaScript:
    var asyncRequest = function()
    {
    	function handleReadyState(o, onSuccess, onFail)
    	{
    		if (o && o.readyState == 4 && o.status == 200)
    		{
    			if (callback)
    			{
    				callback(o);
    			}
    		}
    		else
    		{
    			if (onFail)
    			{
    				onFail(o);
    			}
    			else
    			{
    				alert("An error has occured while trying to connect to the server.");
    			}
    		}
    	}
    	var getXHR = function()
    	{
    		var http;
    		try
    		{
    			http = new XMLHttpRequest;
    				getXHR = function()
    				{
    					return new XMLHttpRequest;
    				};
    		}
    		catch(e)
    		{
    			var msxml = [
    				‘MSXML2.XMLHTTP.3.0&#8242;,
    				‘MSXML2.XMLHTTP,
    				‘Microsoft.XMLHTTP];
    			for (var i=0, len = msxml.length; i < len; ++i)
    			{
    				try
    				{
    					http = new ActiveXObject(msxml[i]);
    					getXHR = function()
    					{
    						return new ActiveXObject(msxml[i]);
    					};
    					break;
    				}
    				catch(e) {}
    			}
    		}
    		return http;
    	};
    	return function(method, uri, onSuccess, onFail, postData)
    	{
    		var http = getXHR();
    		http.open(method, uri + "&stamp=" + new Date, true);
    		handleReadyState(http, onSuccess, onFail);
    		if(postData)
    		{
    			requester.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    			requester.setRequestHeader("Content-length", postData.length);
    		}
    		http.send(postData || null);
    		return http;
    	};
    }();
    about to test it in a sec

    Btw, what's the difference between ++i and i++ ?

  9. #9
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Btw, what's the difference between ++i and i++ ?
    Pre increment, and post increment. In this case it doesn't make a difference. In general, from fastest to slowest, it's pre-decrement, post-decrement, pre-increment, and post-increment:

    Code:
    --i
    i--
    ++i
    i++
    But as mentioned, that has nothing to do with our example.

  10. #10
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    And how would i go about implementing an abort part to the asyncRequest ? the whole layout of has confused me... I'm new to javascript, and heavily used to programming in PHP :P

  11. #11
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cool, thanks ^___^

  12. #12
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    :S
    I tried it and it failed... I checked if anything was returned with firebug and it told me this was returned...

    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    
    <html><head>
    
    <title>403 Forbidden</title>
    
    </head><body>
    
    <h1>Forbidden</h1>
    
    <p>You don't have permission to access /community/htdocs/test.php&amp;stamp=Sun Dec 02 2007 01:09:39 GMT+0000 (GMT Standard Time)
    
    on this server.</p>
    
    </body></html>
    =/ i don't have the permissions to access it ? :S how would i go about changing that ? >.>

  13. #13
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    W00t : ) i tried it with my submit class and it all worked... Well, ish. It updated, but it for some recent it gave me the error "An error occured while trying to receive data from the server." which is the one given to the onFail callback. :S evne though it worked, updated it and brought back the correct data from the server :S

    Why do you think it came back with the permissions error on the other one though ?

  14. #14
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fixed.

    Code Javascript:
    	function handleReadyState(o, onSuccess, onFail)
    	{
    		if (o && o.readyState == 4){
    			if (o.status == 200)
    			{
    				if (onSuccess)
    				{
    					onSuccess(o);
    				}
    			}
    			else
    			{
    				if (onFail)
    				{
    					onFail(o);
    				}
    				else
    				{
    					alert("An error has occured while trying to connect to the server.");
    				}
    			}
    		}
    	}

    Edit: Okay... not completely fixed, for some reason it won't get past the "if (o && o.readyState == 4)" condition. I put alert("hello"); to see if was doing but apparently not... Even though it IS sending it properly and it IS bringing the proper response from the server... :S Any ideas ?

  15. #15
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Awesome. You even implemented your on fail-safe. Very nice. Your next step would be to implement a timer, and poll against how long the query is taking. For example, call the onFail callback if nothing has happened after ~ 5 seconds.

  16. #16
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What should i do about it not going through to the onSuccess callback ?

    I gave it ago at the time out.
    Code Javascript:
    var asyncRequest = function()
    {
    	function handleReadyState(o, timer, onSuccess, onFail)
    	{
    		if (o && o.readyState == 4){
    			clearTimeout(timer);
    			if (o.status == 200)
    			{
    				if (onSuccess)
    				{
    					onSuccess(o);
    				}
    			}
    			else
    			{
    				if (onFail)
    				{
    					onFail(o);
    				}
    				else
    				{
    					alert("An error has occured while trying to connect to the server.");
    				}
    			}
    		}
    	}
    	var getXHR = function()
    	{
    		var http;
    		try
    		{
    			http = new XMLHttpRequest;
    				getXHR = function()
    				{
    					return new XMLHttpRequest;
    				};
    		}
    		catch(e)
    		{
    			var msxml = [
    				'MSXML2.XMLHTTP.3.0',
    				'MSXML2.XMLHTTP',
    				'Microsoft.XMLHTTP'
    			];
    			for (var i=0, len = msxml.length; i < len; ++i)
    			{
    				try
    				{
    					http = new ActiveXObject(msxml[i]);
    					getXHR = function()
    					{
    						return new ActiveXObject(msxml[i]);
    					};
    					break;
    				}
    				catch(e) {}
    			}
    		}
    		return http;
    	};
    	return function(method, uri, onSuccess, onFail, postData)
    	{
    		var http = getXHR();
    		var timer = setTimeout(function()
    		{
    			http.abort();
    			if(onFail)
    			{
    				onFail(http);
    			}
    			else
    			{
    				alert("An error has occured while trying to connect to the server.");
    			}
    		}, 5000);
    		http.open(method, uri + "&stamp=" + new Date, true);
    		handleReadyState(http, timer, onSuccess, onFail);
    		if(postData)
    		{
    			http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    			http.setRequestHeader("Content-length", postData.length);
    		}
    		http.send(postData || null);
    		return http;
    	};
    }();

    But all the ones i tried... Fail, due to the time out, which explains why the onSuccess and onFail weren't being called before, the request isn't making it to ready state 4 :S but shouldn't it be 4 anyway, 'cause it's showing the data has been responded from the server on firebug (and it's the correct data too)

  17. #17
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Perhaps try making your callback param an object with a few properties:

    Code:
    asyncRequest('GET', uri, {
      success: function(o) {
        alert(o.responseText);
      },
      failure: function(o) {
        alert('failed');
      },
      timeout: 5
    });
    Work with that as your implementation, and tweak your interface to support it (hey, there's gotta be a challenge somewhere in all this).

  18. #18
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've barely done anything with javascript, let alone OOP... So this may be way off :P but i quickly whipped this up

    Code Javascript:
    var asyncRequest = function()
    {
    	function defaultSuccess(o)
    	{
    		return function(){alert(o.responseText);};
    	}
    	function defaultFail(o)
    	{
    		return function(){alert("An error has occured. "+o.responseText);};
    	}
    	function handleReadyState(o, timer, onSuccess, onFail)
    	{
    		if (o && o.readyState == 4){
    			clearTimeout(timer);
    			if (o.status == 200)
    			{
    				onSuccess(o);
    			}
    			else
    			{
    				onFail(o);
    			}
    		}
    	}
    	var getXHR = function()
    	{
    		var http;
    		try
    		{
    			http = new XMLHttpRequest;
    				getXHR = function()
    				{
    					return new XMLHttpRequest;
    				};
    		}
    		catch(e)
    		{
    			var msxml = [
    				'MSXML2.XMLHTTP.3.0',
    				'MSXML2.XMLHTTP',
    				'Microsoft.XMLHTTP'
    			];
    			for (var i=0, len = msxml.length; i < len; ++i)
    			{
    				try
    				{
    					http = new ActiveXObject(msxml[i]);
    					getXHR = function()
    					{
    						return new ActiveXObject(msxml[i]);
    					};
    					break;
    				}
    				catch(e) {}
    			}
    		}
    		return http;
    	};
    	return function(method, uri, parameters)
    	{
    		if (parameters)
    		{
    			if (parameters.onSuccess != undefined)
    			{
    				onSuccess = parameters.onSuccess;
    			}
    			else
    			{
    				onSuccess = defaultSuccess();
    			}
    			if (parameters.onFail != undefined)
    			{
    				onFail = parameters.onFail;
    			}
    			else
    			{
    				onFail = defaultFail();
    			}
    			if(parameters.timeout != undefined && typeof(parameters.timeout) == "number")
    			{
    				timeout = parameters.timeout;
    			}
    			else
    			{
    				timeout = 5;
    			}
    			if(paremeters.postData != undefined && typeof(parameters.postData) == "string"){
    				postData = parameters.postData;
    			}
    		}
    		else
    		{
    			onSuccess = defaultSuccess();
    			onFail = defaultFail();
    			timeout = 5;
    		}
     
    		var http = getXHR();
    		var timer = setTimeout(function()
    		{
    			http.abort();
    			onFail(http);
    		}, timeout*1000);
    		http.open(method, uri + "&stamp=" + new Date, true);
    		handleReadyState(http, timer, onSuccess, onFail);
    		if(postData)
    		{
    			http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    			http.setRequestHeader("Content-length", postData.length);
    		}
    		http.send(postData || null);
    		return http;
    	};
    }();

    Added functionality for postData to go through the object parameter too.
    Can't test it yet though, not untill i've fixed the problem of it not making it to readystate 4 even though data has been returned =/ what should i do about that ? I'm completely lost for what to do...
    Last edited by WakeMeWithAKiss; Dec 2, 2007 at 12:19. Reason: typo

  19. #19
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    this part here:
    Code:
    if (parameters.onSuccess != undefined)
                {
                    onSuccess = parameters.onSuccess;
                }
                else
                {
                    onSuccess = defaultSuccess();
                }
                if (parameters.onFail != undefined)
                {
                    onFail = parameters.onFail;
                }
                else
                {
                    onFail = defaultFail();
                }
    should be changed to not invoke the functions right away. You simply want to assign the function. Eg:
    Code:
    if (parameters.onSuccess != undefined)
                {
                    onSuccess = parameters.onSuccess;
                }
                else
                {
                    onSuccess = defaultSuccess;
                }
                if (parameters.onFail != undefined)
                {
                    onFail = parameters.onFail;
                }
                else
                {
                    onFail = defaultFail;
                }
    I just simply removed the parens().
    Anyhow, this is starting to be a lot of code to look at :\
    There are a variety of other 'failure' cases that may happen, but for now, the most important one we're concerned with is the timeout. Here is a revised function that takes those things into account (except I didn't add in your default successes and fails (you can add those back in)).

    Code:
    var asyncRequest = function() {
      function handleReadyState(o, callback) {
        if (o && o.readyState == 4 && o.status == 200) {
          if (callback && callback.onSuccess) {
            window.clearTimeout(Timer);
            callback.onSuccess(o);
          }
        }
      }
      function abort() {
        http.abort();
        if (callback && callback.onFail) {
          callback.onFail();
        }
      }
      var http;
      var getXHR = function() {
        try {
          http = new XMLHttpRequest;
            getXHR = function() {
              return new XMLHttpRequest;
            };
        }
        catch(e) {
          var msxml = [
            'MSXML2.XMLHTTP.3.0',
            'MSXML2.XMLHTTP’,
            'Microsoft.XMLHTTP’
          ];
          for (var i=0, len = msxml.length; i < len; ++i) {
            try {
              http = new ActiveXObject(msxml[i]);
              getXHR = function() {
                return new ActiveXObject(msxml[i]);
              };
              break;
            }
            catch(e) {}
          }
        }
        return http;
      };
      var Timer;
      return function(method, uri, callback, postData) {
        var http = getXHR();
        http.open(method, uri, true);
        handleReadyState(http, callback);
        http.send(postData || null);
        if (callback.timeout) {
          Timer = window.setTimeout(abort, callback.timeout);
        }
        return http;
      };
    }();
    Technically you'd want to fail out on any of these status id's (even when your readyState is 4: 12029, 12030, 12031, 12152, 13030. You'd throw those in a switch statement somewhere checking each case...
    Code:
    case 12002: // Server timeout
    case 12029: // 12029 to 12031 correspond to dropped connections.
    case 12030:
    case 12031:
    case 12152: // Connection closed by server.
    case 13030:
    For now they're probably less important for your case.

  20. #20
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ooops, sorry, didn't know about the () thing... I'm too used to PHP :P

    Wouldn't my time out that i have on atm do the job ? The timer is working fine atm, it's just that after the http request is sent, data is returned (checked in firebug) but it never reachs ready state 4 ('cause i put an 'alert' to tell me if it did... never got the alert). It then times out 5 seconds later.

  21. #21
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've figured out the problem :S but now i'm confused, did it work for you ?

    The problem was that the ready state change function was being called, but not each time the state changes


    changed it too this...
    http.onreadystatechange = handleReadyState(http, timer, onSuccess, onFail);

  22. #22
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Grrr It still only gets to readystate 1 even though data is returned =/

    Edit: managed it

    Right, i've figured i need to put it like this...

    http.onreadystatechange = function(){
    handleReadyState(http, timer, onSuccess, onFail);
    };

    Rather than...

    http.onreadystatechange = handleReadyState(http, timer, onSuccess, onFail);

    And i added alerts to tell me what the state is when it changes.

    Managed to get it to state 4 and 'alert' the returned data fine : D
    and i had a problem with it not calling the onsuccess callback but i've fixed that : D

    Final code
    Code Javascript:
    var asyncRequest = function()
    {
    	function defaultSuccess(o)
    	{
    		return function(){alert(o.responseText);};
    	}
    	function defaultFail(o)
    	{
    		return function(){alert("An error has occured.");};
    	}
    	function abort(http)
    	{
    		http.abort();
    		onFail(http);
    	}
    	function handleReadyState(o, timer, onSuccess, onFail)
    	{
    		if (o && o.readyState == 4){
    			clearTimeout(timer);
    			if (o.status == 200)
    			{
    				onSuccess(o);
    			}
    			else
    			{
    				onFail(o);
    			}
    		}
    	}
    	var getXHR = function()
    	{
    		var http;
    		try
    		{
    			http = new XMLHttpRequest;
    				getXHR = function()
    				{
    					return new XMLHttpRequest;
    				};
    		}
    		catch(e)
    		{
    			var msxml = [
    				'MSXML2.XMLHTTP.3.0',
    				'MSXML2.XMLHTTP',
    				'Microsoft.XMLHTTP'
    			];
    			for (var i=0, len = msxml.length; i < len; ++i)
    			{
    				try
    				{
    					http = new ActiveXObject(msxml[i]);
    					getXHR = function()
    					{
    						return new ActiveXObject(msxml[i]);
    					};
    					break;
    				}
    				catch(e) {}
    			}
    		}
    		return http;
    	};
    	return function(method, uri, parameters)
    	{
    		if (parameters)
    		{
    			if (parameters.success != undefined)
    			{
    				onSuccess = parameters.success;
    			}
    			else
    			{
    				onSuccess = defaultSuccess;
    			}
    			if (parameters.failure != undefined)
    			{
    				onFail = parameters.failure;
    			}
    			else
    			{
    				onFail = defaultFail;
    			}
    			if(parameters.timeout != undefined && typeof(parameters.timeout) == "number")
    			{
    				timeout = parameters.timeout;
    			}
    			else
    			{
    				timeout = 5;
    			}
    			if(parameters.postData != undefined && typeof(parameters.postData) == "string"){
    				postData = parameters.postData;
    			}
    		}
    		else
    		{
    			onSuccess = defaultSuccess;
    			onFail = defaultFail;
    			timeout = 5;
    		}
     
    		var http = getXHR();
    		var timer = setTimeout(function(){
    			abort(http);
    		}, timeout*1000);
    		http.onreadystatechange = function(){
    			handleReadyState(http, timer, onSuccess, onFail);
    		};
    		http.open(method, uri + "&stamp=" + new Date, true);
    		if(postData)
    		{
    			http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    			http.setRequestHeader("Content-length", postData.length);
    		}
    		http.send(postData || null);
    		return http;
    	};
    }();

    What other features could i add ?

  23. #23
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Dude, you are doing awesome.
    Re: Features? You can use Yahoo's Connection Manager for inspiration. It has the ability to pass in arbitrary arguments to your callback. You can use a 'setForm' method, which in return, hijacks the form, and sends all the fields in that form as a post. It also has file upload support etc. Very fun. Nevertheless, it's fun to dive into creating these things yourself as a fun way to learn.

  24. #24
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks ^__^

    I'll have to read up on how to do the file transfer with AJAX first, it's quite a good idea though.
    Hmm for the form thing, i could use the postData variable i already have and check if it's a string (already been processed) or an element (then get all of the post info and process it).
    Maybe even make the postData abit arbitrary ? To pass more than one form. The only problem i can see is if there's some fields with the same name, but i can stack things in arrays of which form it's from and program server side to check for that if it's more than one at once.

    Code Javascript:
    asyncRequest('POST', form.getAttribute("action")+"&xml=true", {
     	success: ContactForm.writeSuccess,
     	failure: ContactForm.writeError,
    	arguements: [passOn, theseVars, toCallback],
    	timeout: 5,
    	postData: [someForm, anotherForm, stringOfPostVars],
    	files: true
    });

    Maybe something like that ?

    I'll work on that after anyway, gonna give a 'form' class a go before (and it's going to have a method for processing all the form bits into a string - then i'll get the AJAX function to use that for form elements passed on).


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •