Jump to content

AJAX


davej

Recommended Posts

So if JQuery is supposed to automatically handle all the different IE XMLHttpRequest object versions then why can't I find that code in the JQuery source? I searched jquery-3.1.0.js for "Microsoft.XMLHTTP" and found nothing. The plain vanilla Javascript code I've been looking at does this...

if (window.XMLHttpRequest){
    xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    var versions = [
     "Microsoft.XMLHTTP",
     "MSXML2.XMLHTTP",
     "MSXML2.XMLHTTP.3.0",
     "MSXML2.XMLHTTP.4.0",
     "MSXML2.XMLHTTP.5.0",
     "MSXML2.XMLHTTP.6.0" ];
    for (var i=0,len=versions.length ; i<len ; i++){
        try{
            xmlhttp = new ActiveXObject(versions[i]);
            break; // breaks out of for-loop on success
        }catch(e){
        }
    }
} else {
    alert("Your browser is too old.\nUpdate your browser.");
}

Is there anything else significant that JQuery handles automagically to simplify AJAX?

 

Link to comment
Share on other sites

jQuery 1.x.x supports old versions of Internet Explorer. jQuery 2.x and above don't.

 

Is there any particular reason you want to support Internet Explorer 6? Internet Explorer 7 and above support the XmlHttpRequest object.

Link to comment
Share on other sites

To create the object, just create an XmlHttpRequest object:

var xmlhttp = new XmlHttpRequest();

Here's an example of how to do a POST request: http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_post2

You have to set the Content-Type header for POST data to work.

 

If the page you're sending data to is a webservice that requires JSON input, just send a JSON string instead of a normal query string. You can convert a Javascript data structure using JSON.stringify().

If the response comes back in JSON format, use JSON.parse() to turn it into a Javascript object.

 

To put it all together into one example:

// The data to be sent
var data = {
  item1 : "Item 1",
  item2 : "Item 2"
};

// Create the request
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = handleResponse;
xhttp.open("POST", "json.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(JSON.stringify(data));


// The function that handles the response
function handleResponse() {
  if (xhttp.readyState == 4 && xhttp.status == 200) {
    var response = JSON.parse(xhttp.responseText);
    console.log(response);
  }
}
Link to comment
Share on other sites

The details are what I find confusing, because this is just uriencoding in the server direction, except they don't add a key such as "json=" so then at the server you can't just use $jsondata = $_POST('json') and what is the advantage of not using a key anyway?

 

Also they don't set the header as JSON...

x.setRequestHeader("Content-Type", "application/json")

 

They don't encode the JSON even though it is being sent as urlencoded...

encodeURIComponent()

 

And when is a length used or needed?

x.setRequestHeader("Content-Length", mydata.length)

 

And then there is also the mysterious "reviver" function...

JSON.parse(text[, reviver])

Link to comment
Share on other sites

You don't need to set the content length, the browser should set it automatically. If you do set it then it should be set to the number of bytes in the request body, not an array length or something like that.

 

The forum trashed my other response.

Link to comment
Share on other sites

You don't need to set the content length, the browser should set it automatically. If you do set it then it should be set to the number of bytes in the request body, not an array length or something like that.

 

The forum trashed my other response.

 

Hmmm, so if there is no advantage to including the content length why would anyone bother with that? With utf-8 strings I don't know if I can count bytes anyway. I don't see any point in not using a short key such as "json="

Link to comment
Share on other sites

strlen will return the correct number of bytes, I think, because I don't think that strlen is multibyte-aware. But, yeah, you don't need to specify the content length, let the browser handle that. If you specify a content length that is wrong then the server will either cut off the response or respond with an error because it didn't think it got everything.

 

Sorry, strlen is PHP, not Javascript.

Link to comment
Share on other sites

I just gave an example without key/value pairs because at my job I often am having to send requests to web services that don't use them. If you're writing both ends of the application, it certainly would be simpler in PHP to send the data in query string variables.

 

You don't need to use the reviver parameter in JSON.parse(), it's just there for if you want to transform values that are read from JSON. MDN had a good explanation and examples about it.

Link to comment
Share on other sites

How about the server response? In that direction is the "Content-Type" "application/json" or not? I've been piddling with a little project for a long time but the problem is that just because something seems to work doesn't prove that it was actually done right.

Link to comment
Share on other sites

It doesn't have to be, the only thing that really matters is the actual content being sent. As long as the response is valid JSON you can parse it on the client side with JSON.parse();

Link to comment
Share on other sites

It depends on your requirements. If you're building the client to look at the content type headers and react differently (for example, if it expects "application/json", but gets "text/plain" and you want to throw an error) then you can set the headers. Or maybe you just want to set them because it feels "more correct". The only reason the server needs to set a content type header for an ajax response is if the response is XML and the Javascript code expects the data to be in the responseXML property instead of the usual responseText property. Otherwise, there's not much a major reason to set the content type header unless your application is specifically validating it.

Link to comment
Share on other sites

So headers won't cause the browser or the server to treat the data any differently?

 

I don't even really understand why there is a xhr.responseXML -- since xml is just text, right?

 

Apparently there is a move toward using a declared xhr.responseType... and one of the types is 'json'

 

https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#the-responseType-attribute

Link to comment
Share on other sites

So headers won't cause the browser or the server to treat the data any differently?

Only in the case of XML.

 

I don't even really understand why there is a xhr.responseXML -- since xml is just text, right?

The responseXML property is a complete DOM tree, not just text. It's only there for the special case when an XML response is sent back with the correct content type, then it will populate the DOM tree for it instead of just leaving it as text. Remember, the X in AJAX stands for XML. I prefer to use JSON, but XML has always had a special case. It's right there in the name, XMLHttpRequest.

 

Apparently there is a move toward using a declared xhr.responseType... and one of the types is 'json'

That's how it should have been done from the start, XML should never have been a specific part of it. Ajax requests have nothing to do with XML (and for that matter, nothing to do with asynchronous either). It's just a way for the browser to send a request through Javascript. That's why I don't capitalize ajax anymore, the acronym is fairly useless at this point (if I make a synchronous request that returns JSON, it's still an ajax request).

 

But yeah, it should have been that way from the start. Instead of special handling for "XML or everything else", it should have had a generic type property and a generic response property, and the response would be different based on the type. A type of "document" or "XML" would result in the response automatically being parsed in the DOM, a type of "json" would result in the response automatically being parsed for JSON, etc. It's hardly necessary, it really only saves a single step for the programmer, but that should have been the way it was done instead of defining special rules and properties for XML only.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...