Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    New Coder
    Join Date
    Jan 2013
    Posts
    74
    Thanks
    19
    Thanked 1 Time in 1 Post

    Ajax call requests not working in all browsers

    I've been using a rather simple Ajax call to make forms a little more streamlined and responsive, but I've had some people say it doesn't work in their browser - specifically Chrome, even though I am running Chrome and it works fine. I was just wondering if there is an alternative to this method, which I'm sure is now ancient anyway:

    This is the basic HTML, and I want the result to display in the DIV show_here
    Code:
    <select name="test" onclick="displayResult(this.value)">
    <option value="value1">Value 1</option>
    </select>
    <div id="show_here"></div>
    This is the Ajax call:

    Code:
    var xmlhttp;
    
    function displayResult(item_selected){
    xmlhttp=GetXmlHttpObject();
    if (xmlhttp==null){
      alert ("Browser does not support HTTP Request");
      return;
      }
    var url="process_result.php";
    url=url+"?selection="+item_selected;
    url=url+"&sid="+Math.random();
    xmlhttp.onreadystatechange=stateChanged;
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
    }
    
    function stateChanged(){
    if (xmlhttp.readyState==4){
    document.getElementById("show_here").innerHTML=xmlhttp.responseText;
    }
    }
    //**************************************************//
    function GetXmlHttpObject(){
    if (window.XMLHttpRequest){
      // code for IE7+, Firefox, Chrome, Opera, Safari
      return new XMLHttpRequest();
      }
    if (window.ActiveXObject){
      // code for IE6, IE5
      return new ActiveXObject("Microsoft.XMLHTTP");
      }
    return null;
    }
    Then I would just have a PHP script (process_result.php) to display the proper code based on the selection fed to it. It's pretty basic and it's worked fine for a while, but now apparently it's not working so good.

    Is there something better that should be used now? Or is there something inherently wrong with this code/method?

  • #2
    Senior Coder
    Join Date
    Dec 2010
    Posts
    2,396
    Thanks
    12
    Thanked 569 Times in 562 Posts
    A few things that should make things work

    1. You don't need the browser differentiation any more. Since IE7 each browser perfectly supports the XMLHttpRequest object
    2. You should assign onreadystatechange after the call to open
    3. You need to make parameters and their values URI compliant. There is encodeURIComponent() to assure this
    4. You should check for both readyState==4 and status=200 for a successful request
    5. You should use onchange for a select box instead of onclick
    Code:
    <select name="test" onchange="displayResult(this.value)">
    <option value="value1">Value 1</option>
    </select>
    <div id="show_here"></div>
    Code:
    var xmlhttp;
    
    function displayResult(item_selected){
      xmlhttp=GetXmlHttpObject();
      var url="process_result.php";
      url=url+"?selection="+encodeURIComponent(item_selected);
      url=url+"&sid="+Math.random();
      xmlhttp.open("GET",url,true);
      xmlhttp.onreadystatechange=stateChanged;
      xmlhttp.send(null);
    }
    
    function stateChanged(){
      if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById("show_here").innerHTML=xmlhttp.responseText;
      }
    }
    //**************************************************//
    function GetXmlHttpObject(){
      return new XMLHttpRequest();
    }

  • The Following 2 Users Say Thank You to devnull69 For This Useful Post:

    Arbitrator (08-29-2013), cgdtalent (08-29-2013)

  • #3
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by cgdtalent View Post
    I was just wondering if there is an alternative to this method, which I'm sure is now ancient anyway:
    Here's a version I have in one of my pages:

    Code:
    var symbols = {
    	request: new XMLHttpRequest(),
    	document: null,
    	documentSymbols: null,
    	elements: [],
    	width: 512, // in SVG coordinate space
    	height: 512 // in SVG coordinate space
    };
    symbols.request.addEventListener("readystatechange", function () {
    	if (symbols.request.readyState === XMLHttpRequest.DONE && symbols.request.statusText === "OK") {
    		if (symbols.request.responseXML instanceof Document) {
    			symbols.document = document.adoptNode(symbols.request.responseXML.documentElement);
    		}
    		else { // Windows Internet Explorer 9
    			symbols.request = new DOMParser().parseFromString(symbols.request.responseText, "application/xml");
    			symbols.document = document.adoptNode(symbols.request.documentElement);
    		}
    	}
    }, false);
    symbols.request.open("get", "images/symbols.svg", false);
    symbols.request.send();
    symbols.documentSymbols = symbols.document.getElementsByTagNameNS(namespaces.SVG, "svg");
    while (symbols.documentSymbols.length > 0) {
    	symbols.elements.push(symbols.documentSymbols[0].parentNode.removeChild(symbols.documentSymbols[0]));
    }
    This allows me to get and process the imported document as nodes. It's only designed to work in IE9 and later though.

    Quote Originally Posted by devnull69 View Post
    2. You should assign onreadystatechange after the call to open
    Is there a practical reason for this or is this just preference? If you set the event listener before, it should just remain dormant until it's needed, so I don't see what difference this makes.

    Quote Originally Posted by devnull69 View Post
    4. You should check for both readyState==4 and status=200 for a successful request
    Hmm... I didn't think of that. I added this to my code, though I used statusText instead since an "OK" response seems more meaningful than "200".
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #4
    Senior Coder
    Join Date
    Dec 2010
    Posts
    2,396
    Thanks
    12
    Thanked 569 Times in 562 Posts
    Quote Originally Posted by Arbitrator View Post
    Is there a practical reason for this or is this just preference? If you set the event listener before, it should just remain dormant until it's needed, so I don't see what difference this makes.
    It can make a difference if you send more than one successive requests, especially for (older versions of) Internet Explorer. It fired the readystatechange event with readyState==4 even though it had just been assigned (before .open() was called).

  • #5
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by devnull69 View Post
    It can make a difference if you send more than one successive requests, especially for (older versions of) Internet Explorer. It fired the readystatechange event with readyState==4 even though it had just been assigned (before .open() was called).
    I tried researching this and found sources indicating that this is an IE6 and IE7 issue without much detail. Every complete example I saw exhibiting the issue used the ActiveX object.

    The Microsoft documentation says to create the listener after the open method is invoked, but is also light on details. It indicates that this allows some kind of reset, but provides no examples. (I sent them an email asking them to update the article.)

    The W3C spec always puts the event listener before open() or after send(). Putting it after doesn't make much sense to me since you may miss states if they occur before the event listener gets assigned.

    I'd just explicitly reset a connection by either deleting the variable representing the request (delete symbols.request) in the above example, creating a re-usable function that automatically reinitializes the variables, or by invoking the abort function to explicitly terminate the connection.
    For every complex problem, there is an answer that is clear, simple, and wrong.


  •  

    Posting Permissions

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