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:
- Did I forget an important part of HTTP/RESTful services that might be needed in a framework?
- Can there be efficiency-improvements?
- Are there any other bugs/inconsistencies/possible improvements?