Showing posts with label XMLHttpRequest. Show all posts
Showing posts with label XMLHttpRequest. Show all posts

Monday, October 13, 2008

JavaScript XMLHttpRequest Wrapper

Here is my version of the XMLHttpRequest Wrapper, Open Source, and available on Google Code. Enjoy.

Here is a simple example of a http request with the lib:

new fiji.xhr('get', 'echo.php?param=value', function(xhr) {
   if (this.readyState == 4 && this.status == 200) {
      alert(this.responseText);
   }
}).send();

The readystate callback handler executes in the scope of the XHR Instance. So you can use the this keyword to reference the XHR object instance. This behavior is the same as the specifications for the callback scope in the W3C XMLHttpRequest Specs. You can also receive a reference to the XHR library instance which is passed as the first parameter to the callback. In the case above it would be xhr. This allows you to attach further references or objects to the XHR library instance that would be persisted for the duration of the XHR call. For example, a request ID.

Thursday, February 14, 2008

Hacking Google Suggest (complete) with JavaScript Remoting

Google Suggest is an feature of the Google Search Engine User Interface and Server that creates suggestions (auto-completes) your search keywords.

This is performed using AJAX. Google will send the first few letters or word(s) you type into the Search Input back to the Google Server using the XMLHttpRequest Object (or a similar AJAX method)

When I type in the search keywords "javascript". I can watch the XMLHttpRequests created by Google Search using Firefox's Firebug extension. Google creates 5 XMLHttpRequests, each one a few letters more then the previous.

The Google Suggest XMLHttpRequests

  • http://www.google.com/complete/search?hl=en&client=suggest&js=true&q=ja - does not complete
  • http://www.google.com/complete/search?hl=en&client=suggest&js=true&q=java - completes and returns:
    window.google.ac.Suggest_apply(frameElement, "java", new Array(2, "java download", "21,600,000 results"
    
    , "java api", "9,000,000 results", "java runtime", "2,510,000 results", "java.com", "1,350,000 results"
    
    , "java update", "11,500,000 results", "javascript tutorial", "1,490,000 results", "java string", "3
    
    ,920,000 results", "java runtime environment", "894,000 results", "javanoid", "71,000 results", "java
    
     virtual machine", "2,050,000 results"), new Array(""));
  • http://www.google.com/complete/search?hl=en&client=suggest&js=true&q=javasc - completes and returns:
    window.google.ac.Suggest_apply(frameElement, "javasc", new Array(2, "javascript tutorial", "1,490,000
    
     results", "javascript substring", "120,000 results", "javascript redirect", "291,000 results", "javascript
    
     download", "20,300,000 results", "javascript replace", "283,000 results", "javascript settimeout", "198
    
    ,000 results", "javascript split", "251,000 results", "javascript indexof", "130,000 results", "javascript
    
     switch", "1,150,000 results", "javascript string replace", "153,000 results"), new Array(""));
    
  • http://www.google.com/complete/search?hl=en&client=suggest&js=true&q=javascri - does not complete
  • http://www.google.com/complete/search?hl=en&client=suggest&js=true&q=javascript - completes and returns:
    window.google.ac.Suggest_apply(frameElement, "javascript", new Array(2, "javascript tutorial", "1,490
    
    ,000 results", "javascript substring", "120,000 results", "javascript redirect", "291,000 results", "javascript
    
     download", "20,300,000 results", "javascript replace", "283,000 results", "javascript settimeout", "198
    
    ,000 results", "javascript split", "251,000 results", "javascript indexof", "130,000 results", "javascript
    
     switch", "1,150,000 results", "javascript string replace", "153,000 results"), new Array(""));
    

As you can see, each response is a JavaScript function call. Google Search makes the XMLHttpRequest call asynchronously as you type your search query, and aborts the last XMLHTTPRequest if you type more than 2 to 3 letters. Each XMLHttpRequest result is a call to the method: window.google.ac.Suggest_apply(). What what can do is create this method in our JavaScript, and wait for Google Suggest to call it with the suggested keywords and their "weight" as parameters.

Hacking Google Suggest for our own use

Now the fun part. What we do is make a HTTP request to the Google URL http://www.google.com/complete/search?hl=en&client=suggest&js=true&q={q}, where q is our keyword. Google will then return the Google Search Suggestions for that keyword.

Try it by clicking: http://www.google.com/complete/search?hl=en&client=suggest&js=true&q=javascript

Now that we know how to get Google Suggest results from the Google server, we can implement it with JavaScript. Due to the XMLHttpRequest Same Domain Policy, we cannot use the XMLHttpRequest Object. However, the results of each Google Suggest query is javascript, so we can use JavaScript Remoting.

Here is an example:

Try our Google Suggest Hack yourself. View source to see how it works.

Saturday, February 9, 2008

Native (W3C) XMLHttpRequest for IE6 and earlier browsers

With IE7 implementing XMLHttpRequest as a native JavaScript Object, the need to fork JavaScript for XMLHttpRequest is now limited to IE6 and earlier major browsers.

Here is my wrapper for IE6 and lower browsers so you can use the XMLHttpRequest syntax in those browsers also.

/**
* Emulate window.XMLHttpRequest in IE6-
*/
if (!window.XMLHttpRequest) {
 var ms_xhr_ver = false;
 window.XMLHttpRequest = function() {
  if (ms_xhr_ver) return new ActiveXObject(ms_xhr_ver);
  var xhr = false;
  var versions = [
  "Msxml2.XMLHTTP.7.0", 
  "Msxml2.XMLHTTP.6.0", 
  "Msxml2.XMLHTTP.5.0", 
  "Msxml2.XMLHTTP.4.0", 
  "MSXML2.XMLHTTP.3.0", 
  "MSXML2.XMLHTTP",
  "Microsoft.XMLHTTP"];
  var n = versions.length;
  for (var i = 0; i <  n; i++) {
   try {
    if (xhr = new ActiveXObject(versions[i])) {
     ms_xhr_ver = versions[i];
     break;
    }
   } catch (e) { /* try next */ }
  }
  return xhr;
 };
}

Here is some example usage:

/**
* Example usage of native XHR in IE6
*/
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { 
 if (xhr.readyState == 4) {
  if (xhr.status == 200) {
   alert(xhr.responseText);
  }
 }
};
xhr.open('get', '/2008/02/native-w3c-xmlhttprequest-for-ie6-and.html');
xhr.send('');

Try It

You'll notice that you can use the same syntax in all major browsers, Firefox, IE6, IE7, Safari etc. There is not branching of code once you have emulated native XMLHttpRequest for IE6 and earlier browsers. This can be a good base to either make XMLHttpRequest requests directly, or to build your XMLHttpRequest library.

While I'm on the topic, I'd like to point out a major flaw in some popular XMLHttpRequest libraries. They wrap the ActiveX based XHR of IE6 and earlier before wrapping the native XMLHttpRequest. This will make IE7 use the older version of XMLHttpRequest.

Next I think I'll blog about cross-domain XMLHttpRequest.