Generalized Ajax function
Your code seems fairly robust, but it is inefficient. Here are a few ways you could speed it up.


Reuse request objects. There is a good bit of overhead creating these, so you definitely want to be reusing these if you are making more than a few requests per page. But be careful - some older browsers have strange quirks about reused request objects.
Don't make a new function for every onreadystatechange. The function is executed with xmlhttp as the context, so, within that function, this === xmlhttp.
Whenever possible, cache. You can cache whether the browser supports XMLHTTPRequest or ActiveX so you don't check every time the function is called.
synchronous requests are usually a bad idea. Are you sure you should be using them? If not, don't write code that is more general than it needs to be. It will just make the function less efficient.


Also, you're missing a semicolon.

As an example, here's a loader function I wrote a while ago. The feature set is a little different than yours - it doesn't support synchronous requests, but it does support error handlers, data encoding, and timeouts - and behind the scenes it implements all the optimizations above. Like your code, it results in a single function; the simplest use case would be load('log.php');.

/***
* load.js
*   Simplifies use of ajax.
* parameters
*   url     : String : address of requested content
*   options : Object : (optional) additional parameters. All keys are optional.
*     onload  : Function : passed request.responseText on success
*     onfail  : Function : passed status on status!=200 or 'timeout' on timeout
*     post    : Object   : POST key-value pairs. GET is used when post==false
*     timeout : Number   : seconds to wait before aborting request
***/

var load=(function() {
    var pool=[],
        getReq=window.XMLHttpRequest?
            function() {return new XMLHttpRequest();}:
            function() {return new ActiveXObject('Microsoft.XMLHTTP');};
    function statechange() {
        if(this.readyState==4) {
            clearTimeout(this.t);
            this.onreadystatechange=null;
            pool[pool.length]=this;
            var fn=this.o[this.status==200?'onload':'onfail'];
            delete this.o;
            fn&amp;&amp;fn(this.status==200?this.responseText:this.status);
        }
    }
    return function(url,options) {
        var req,t,data='';
        req=pool.length?pool.pop():getReq();
        req.o=options=options||{};
        if(options.post) {
            for(t in options.post)
                data+='&amp;'+encodeURIComponent(t)+'='+encodeURIComponent(options.post[t]);
            data=data.substring(1);
            req.open('POST',url,true);
            req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
        } else {
            req.open('GET',url,true);
        }
        req.onreadystatechange=statechange;
        req.send(data||undefined);
        if(options.timeout) {
            req.t=setTimeout(function() {
                req.onreadystatechange=null;
                req.abort();
                pool[pool.length]=req;
                if(req.o.onfail)
                    req.o.onfail('timeout');
            },options.timeout*1000);
        }
    };
})();