4
\$\begingroup\$

I wrote an Ajax function, which should be used in a framework to interact with a webserver.

The (self-written) Java-Webserver can be used to fetch files and folder-contents, create files and folders, and delete them.

/**
 * Performs an Ajax-Request
 * @param  {string}   method            HTTP-Method
 * @param  {string}   url
 * @param  {string}   postData          optional; HTTP-body
 * @param  {string}   contentType       optional; default: "multipart/form-data"
 * @param  {object}   authentication    optional; loginCredentials for basicAuth; {"user": "userName", "password": "password"}
 * @param  {function} callback          optional; called, if the operation succeeded;
 *                                              Parameter: (string) response-body
 * @param  {function} errorCallback     optional; called, if the operation failed;
 *                                              Parameter: 1 = (number) statusCode; (==0, if the given parameters were invalid)
 *                                                         2 = (string) statusText; (or errorMessage, if statusCode == 0)
 */
function ajax(method, url, postData, contentType, authentication, callback, errorCallback) {
    if(typeof(errorCallback) != 'function'){
        errorCallback = function(){};                           //Dummy-function to reduce code
    }

    //Validate the input parameters
        if(["GET", "HEAD", "POST", "PUT", "DELETE"].indexOf(method) < 0){
            return errorCallback(0, "Invalid method");
        }
        if(postData && ["HEAD", "POST"].indexOf(method) < 0){          //Other methods don't support postData
            return errorCallback(0, "Invalid method for postData");
        }
    //Get a cross-browser XML-HTTP-Object:
        var req = createXMLHTTPObject();
        if (!req) {
            return errorCallback(0, "Ajax is not supported");   //Oops! Something bad happened
        }
        req.open(method, url, true);    //async = true
    //Manipulate header-fields:
        //req.setRequestHeader('User-Agent','XMLHTTP/1.0');
        if(postData){
            if(contentType){
                req.setRequestHeader('Content-type', contentType);
            }else{
                req.setRequestHeader('Content-type', 'multipart/form-data');
            }
            //key-value pairs with binary data or big payloads:
            //    multipart/form-data
            //key-value pairs with few non-alphanumerical symbols:
            //    application/x-www-form-urlencoded
            //binary data:
            //    application/octet-stream
        }
        if(authentication){
            req.setRequestHeader("Authorization", "Basic " + btoa(authentication.user + ":" + authentication.password));    //btoa() = encode string to base64
        }
        req.overrideMimeType("text/plain; charset=utf-8");      //The browser must not execute javascript-files, if they're loaded with this method
    //Prepare execution:
        req.onreadystatechange = function () {
            if (req.readyState != 4) {
                return;
            }
            if (req.status != 200 && req.status != 304) {
                return errorCallback(req.status, req.statusText);
            }
            if(typeof(callback) == 'function'){
                callback(req.response);
            }
        }
        if (req.readyState == 4){
            return;
        }
        req.send(postData);
}

The createXMLHTTPObject()-Method returns either an XMLHttpRequest-Object, or an ActiveXObject-Object to reach cross-browser compatibility.

The whole function should be cross-browser compatible, but doesn't have to support older browsers, as the Framework itself depends upon HTML5.

The code is based on this example

As I'm not 100% familiar with the HTTP-Protocol, I have the following questions:

  1. Did I forget an important part of HTTP/RESTful services that might be needed in a framework?
  2. Can there be efficiency-improvements?
  3. Are there any other bugs/inconsistencies/possible improvements?
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

Support for JSONP and CORS is a must for any modern web framework.

APIwise, I think you'd want to reduce the arguments to your method to a single object, similar to how jQuery does it. It gives an opportunity to give defaults, and simplifies it from the API perspective. As it stands, it will be painful to use, in that you need to remember a lot of arguments. A simple GET ajax with your's:

ajax('GET', 'index.html', null, null null function(evt) {
    console.log("Success!")
})

vs jQUery or similar:

ajax({method:'GET', url:'index.html'}, success:function(evt) {
    console.log("Success!")
})
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.