Tuesday, November 10, 2009

XMLHttpRequest

I recently wanted to get information from a web interface, I just wanted to send a query to the server, and get a response. XMLHttpRequest does just that. I choose to implement it using JavaScript, that seems to be the most common way.


The following code sends a GET request to www.google.com


var url = "www.google.com";
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send(null);
textArea.value = request.responseText;

The false entry in the call to the open function means that this call isn't asynchronous, that is, the script will pause until it gets a response from the server before continuing running. The null parameter in the send method doesn't seem to be necessary, but it's supposed to be there. responseText is the result as plain text returned by the server. If the response is valid XML, that will be stored in responseXML.


Not terribly exciting looking at the source code for the front page of Google though . Luckily Google uses GET for it's searches, so we can easily modify the URL to this:


var url = "http://www.google.com/search?q=IBM";
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send(null);
textArea.value = request.responseText;

Or even:


var term = "IBM";
var url = "http://www.google.com/search?q=" + term;
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send(null);
textArea.value = request.responseText;

We will now get the search results for the search term IBM. Mind you it's just the source code for the result page, it's not very pretty, but the information is there.


If we want to use the POST method, things get a bit trickier since we can't just modify the URL.


var param = "search?q=IBM";
var url = "http://www.google.com";
var request = new XMLHttpRequest();
request.open("POST", url, false);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", param.length);
request.setRequestHeader("Connection", "keep-alive");
request.send(param);

So, what's new here? The first one is the param variable. It's pretty much what would have been added after the URL had this been a GET request. Next we can see that we now call the open method with the POST parameter. Then we need to specify the HTTP headers that has to be in a POST request. Finally we can see that we are now sending our parameter to the send method instead of attaching it to the end of the URL.


I used all this to interface with a site that I didn't control. Luckily, since I did it in an HTA, it worked. When I tried it as a website it wouldn't work. I'm assuming that it's because of the same origin policy in my browser. It's not allowing me to load something from another site then the one the script is running in. I'm sure there's a way around that, but so far my HTA is working fine anyway.

No comments: