Frågan#1
Har knackat ihop en Javascriptfunktion för att enkelt kunna arbeta med AJAX i framtiden inom det projekt jag arbetar med just nu.
Jag är dock ingen Javascript-guru, så det vore trevligt om någon kan kolla över och se ifall det är något som kan eller BÖR ändras.
Notera att om man begär data tillbaka som JSON så krävs det att JSON objektet inkluderas innan (alternativt att man använder sig av en nyare webbläsare som har JSON objektet som standard).
//
// Function ´ajaxCall(Array settings)´.
// ajaxCall attempts to create a XmlHttpRequest object depending on settings defined by function call.
//
// Settings are defined in a value-pair order and the following can be defined:
//
// Setting Default value Type Description
// ---------------------------------------------------------------------------------------------------
// async: true boolean Whether to use asynchronous call or not
// dataType: undefined string Set this to JSON if the data returned is JSON encoded to parse it as a array object (note that JSON object must exist! Otherwise it will be undefined)
// error: undefined eval Code to be executed on any error
// method: GET string Connection method (GET, POST, HEAD)
// params: undefined string Parameters to send with URL (foo=bar&foo2=bar2)
// statusCode: undefined array eval Define an array with HTTP status codes and code to be executed for each HTTP status code (e.g. 404, 503...)
// success: undefined eval Code to be executed on a successful call
// url: undefined string The URL to where to open the connection
//
//
// Both error and success settings will return following values:
//
// returnStatus Returns true when AJAX call was successful, or false on failure
// returnStatusMsg Returns any errors in clear text
// ajaxObj Returns the full XmlHttpRequest object on success
//
//
// Usage example:
//
// AjaxGetInfo = function() { ajaxCall({
// method: 'GET',
// async: false,
// statusCode: {404: function() {
// alert('Could not find the page I was looking for!');
// },
// 503: function() {
// alert('The server is doooown!');
// }
// },
// url: "http://www.myurl.com",
// params: 'foo=bar&foo2=bar2',
// success: function (returnStatus, returnStatusMsg, ajaxObj) {
// alert('Everything went well!\n\n' +
// 'returnStatus: ' + returnStatus + '\n' +
// 'returnStatusMsg: ' + returnStatusMsg + '\n' +
// 'ajaxObject: ' + ajaxObj + '\n' +
// 'HTTP status Code: ' + ajaxObj.status + '\n' +
// 'Data returned: ' + ajaxObj.responseText);
// },
// error: function (returnStatus, returnStatusMsg, ajaxObj) {
// alert('An error has occured!\n\n' +
// 'returnStatus: ' + returnStatus + '\n' +
// 'returnStatusMsg: ' + returnStatusMsg + '\n' +
// 'ajaxObject: ' + ajaxObj + '\n' +
// 'HTTP status Code: ' + ajaxObj.status + '\n' +
// 'Data returned: ' + ajaxObj.responseText);
// }
// });
// };
//
// // Get some information from some page
// AjaxGetInfo();
//
function ajaxCall(settings) {
// Define default settings
if (!settings.method) { settings.method = 'GET'; } // Define default method
if (!settings.async) { settings.async = true; } // Define asynchronous calls as default
// Prepare variables
var method_allowed = false;
var url_full = '';
// Prepare return array
var returnArray = new Array(); // Create return array
returnArray.status = false; // Default return status
returnArray.status_msg; // Status message containing clear text return message
returnArray.ajaxObject; // Contains the XmlHttpRequest object if available
returnArray.parseError; // If any return functions gives a parse error (settings.success/settings.error)
returnArray.jsonData; // If settings.dataType is defined as JSON, then the jsonData will be stored in this object
// Private function ´priv_error(str error_msg, str error_details)´
// Alerts a error message specified in arg ´error_msg´ with details in arg ´error_details´.
function priv_error(error_msg, error_details) {
errMsg = 'ajaxCall error!\n\n';
errMsg += 'Error:\n';
errMsg += error_msg + '\n\n';
errMsg += 'Details:\n';
errMsg += error_details;
alert(errMsg);
}
// Private function ´priv_user_onError(null)´
// Attempts to evaluate user defined code in param ´settings.error´.
// Calls private function ´priv_error´ if eval halted on a parse error.
function priv_user_onError() {
if (typeof(settings.error != 'undefined')) {
// Attempt to evaluate user defined function with returning results
try {
eval("settings.error(" + returnArray.status + ", '" + returnArray.status_msg + "', returnArray.ajaxObject, returnArray.jsonData);");
}
catch (err_onError) {
// If eval function returned a parse error, then return error message
priv_error('Parse error occured while evaluating user-defined function settings.error().', err_onError);
}
}
}
// Private function ´priv_user_onSuccess(null)´
// Attempts to evaluate user defined code in param ´settings.success´.
// Calls private function ´priv_error´ if eval halted on a parse error.
function priv_user_onSuccess() {
if (typeof(settings.success != 'undefined')) {
// Attempt to evaluate user defined function with returning results
try {
// Define status as successful (true)
returnArray.status = true;
// If settings.dataType is defined as ´JSON´
if (settings.dataType.toUpperCase() == 'JSON') {
if (typeof(JSON) == 'object') {
returnArray.jsonData = JSON.parse(returnArray.ajaxObject.responseText);
}
}
eval("settings.success(" + returnArray.status + ", '" + returnArray.status_msg + "', returnArray.ajaxObject, returnArray.jsonData);");
}
catch (err_onSuccess) {
// If eval function returned a parse error, then return error message
priv_error('Parse error occured while evaluating user-defined function settings.success().', err_onSuccess);
}
}
}
// Private function ´priv_user_onStatuscode(str status_code)´
// Attempts to evaluate user defined code in array value of param ´settings.statusCode[str status_code]´.
// Calls private function ´priv_error´ if eval halted on a parse error.
function priv_user_onStatuscode(status_code) {
if (typeof(settings.statusCode[status_code] != 'undefined')) {
// Attempt to evaluate user defined function with returning results
try {
// Define statys as successful (true)
returnArray.status = true;
eval("settings.statusCode[status_code]()");
}
catch (err_onStatuscode) {
// If eval function returned a parse error, then return error message
priv_error('Parse error occured while evaluating user-defined function settings.statusCode().', err_onStatuscode);
}
}
}
// Define allowable methods. Shall only be methods available in the XmlHttpRequest object
// defined in the work draft on http://www.w3.org/TR/XMLHttpRequest/
var methods_allowed = new Array('GET', // Request URI
'POST', // Send data to server
'HEAD'); // Request URI without body
// Make sure that provided method is allowed
for (i=0; i < methods_allowed.length; i++) {
if (settings.method == methods_allowed[i]) {
method_allowed = true;
break;
}
}
// If method is not allowed
if (!method_allowed) {
returnArray.status_msg = "Non-allowed method defined (" + settings.method + ") in arg \\'method\\'.";
priv_user_onError();
}
// If no URL is defined or if it is empty
else if (!settings.url) {
returnArray.status_msg = "No URL identifier defined in arg \\'url\\'.";
priv_user_onError();
}
// If all prechecking is complete, attempt to create AJAX object
else {
// Create full URL with any additional parameters included in URL
url_full = settings.url;
if (settings.params) {
// If the method defined is not POST, then add the parameters to the full URL
if (settings.method != 'POST') {
url_full += '?' + settings.params;
}
}
// Attempt to create AJAX object
var xhr;
try { xhr = new ActiveXObject('Msxml2.XMLHTTP'); }
catch (e) {
try { xhr = new ActiveXObject('Microsoft.XMLHTTP'); }
catch (e2) {
try { xhr = new XMLHttpRequest(); }
catch (e3) {
// If AJAX object could not be created
xhr = false;
returnArray.status_msg = 'Could not create AJAX object.';
priv_user_onError();
}
}
}
// If AJAX object exists
if (xhr) {
returnArray.ajaxObject = xhr;
xhr.onreadystatechange = function() {
// Wait for AJAX to receive all data from server
if (xhr.readyState == 4) {
// If user defined status code exists in ´settings.statusCode´ and if it
// matches current AJAX status code returned
if (typeof(settings.statusCode[xhr.status]) != 'undefined') {
priv_user_onStatuscode(xhr.status);
}
else {
// Consider AJAX call to be successful when HTTP status code is 200 and when AJAX readyState is 4
if (xhr.status == 200) {
priv_user_onSuccess();
}
// If not, then call private function ´priv_user_onError()´
else {
priv_user_onError();
}
}
}
};
// Open the AJAX connection and send the data
xhr.open(settings.method, url_full, settings.async);
// When method is GET, do not send the params with the send() method
if (settings.method == 'GET') {
xhr.send(null);
}
// When the method is POST, send the params together with the send() method
else if (settings.method == 'POST') {
xhr.send(settings.params);
}
// When the method is anything else other than defined above
else {
xhr.send(null);
}
}
// If AJAX object does not exist
else {
returnArray.status_msg = 'AJAX object does not exist.';
priv_user_onError();
}
}
}
Exempel på användande:
//
// Example of using ajaxCall() function
//
getUsrSetting = function() { ajaxCall({
method: 'GET',
async: true,
dataType: 'json',
statusCode: {404: function() {
alert('Hmm.. Page seem to be down at the moment!');
},
503: function() {
alert('The server is doooooown!');
}
},
url: "./winform.php",
params: 'formID=CMSWIN__main&opener=init_session&AJAX_get_usersetting=test_setting&user=1',
success: function (returnStatus, returnStatusMsg, ajaxObj, jsonData) {
alert('User setting value:\n\n' +
jsonData.setting_value);
},
error: function (returnStatus, returnStatusMsg, ajaxObj, jsonData) {
alert('Could not get user setting. Some debug:\n\n' +
'returnStatus: ' + returnStatus + '\n' +
'returnStatusMsg: ' + returnStatusMsg + '\n' +
'ajaxObj: ' + ajaxObj + '\n' +
'Status Code: ' + ajaxObj.status + '\n' +
'returnData: ' + ajaxObj.responseText);
}
});
};
// Run the function
getUsrSetting();
Kommentarer, förbättringsförslag etc uppskattas!
Observera att konceptet bygger på jQuerys AJAX funktionalitet men detta fungerar utmärkt utan jQuery.
Tack på förhand!