1 var Ozone = Ozone || {}; 2 Ozone.util = Ozone.util || {}; 3 4 5 /** 6 * @class 7 * @private 8 * 9 * @description 10 * Object used to talk to the cross domain and locally. If the server is local, 11 * then AJAX will be used. If the server is remote, then we must use a 12 * hack to get around Same Origin Policy and make the call cross domain. 13 * 14 * @requires util.js 15 */ 16 Ozone.util.Transport = { 17 version: Ozone.version.owfversion + Ozone.version.preference 18 }; 19 20 21 /** 22 * @private 23 * 24 * @params cfg.url - url of the request 25 * cfg.method - HTTP verb (only POST or GET, use _method = PUT or DELETE with a POST ) 26 * cfg.onSuccess - callback function to capture the success result 27 * cfg.onFailure - callback to execute if there is an error 28 * cfg.content - optional content to send with the request, ie {value: 'x', _method: 'PUT'} 29 * cfg.async - optional (default is true, asynchronous send, only applies to Ajax call) 30 * cfg.handleAs - text or json 31 * cfg.autoSendVersion - true to send owf version to the server, false don't send (defaults to true) 32 * cfg.ignoredErrorCodes - optional array of http error codes to ignore (if these happen onSucess will be called) 33 * cfg.forceXdomain - optional flag to force xdomain ajax call using dojo window.name 34 * 35 * @returns void, use callbacks 36 * 37 * Static method. Must use 2 callbacks since javascript is asyncronous 38 * we have to wait for the response. 39 * 40 * This implementation uses the dojox.windowName hack for a remote server, 41 * but could be replaced with something else like JSONP if desired 42 */ 43 Ozone.util.Transport.send = function(cfg) { 44 if (Ozone.log) { 45 Ozone.log.getDefaultLogger().debug('Transport Send', cfg.url, cfg.method, cfg.content); 46 } 47 48 var defaultFailure = function(err) { 49 // If error is an HTML page, just use body 50 if (err == undefined || err == null) err = ""; 51 var start = err.indexOf("<body"); 52 if (start > -1) { 53 // start at the end of the body tag 54 start = err.indexOf(">", start) + 1; 55 var stop = err.indexOf("</body>", start); 56 57 if (stop > -1) err = err.substring(start, stop); 58 else err = err.substring(start); 59 } 60 61 if (!Ozone.Msg) 62 Ozone.util.ErrorDlg.show(err,200,50); 63 else 64 Ozone.Msg.alert('Server Error',err,null,this,{ 65 cls: "owfAlert" 66 }); 67 }; 68 69 // create an onFailure method if one doesn't exist 70 if (!cfg.onFailure) { 71 cfg.onFailure = function(err){ 72 defaultFailure(err); 73 }; 74 } 75 76 var methodToUse = cfg.method; 77 var hasBody = false; 78 if (methodToUse == "PUT" || methodToUse == "DELETE") 79 { 80 methodToUse = "POST"; 81 } 82 83 if (methodToUse == "POST") { 84 hasBody = true; 85 } 86 87 if(cfg.content == null) { 88 cfg.content = {}; 89 } 90 91 //autoSendVersion to server default behavior is true 92 if (!(cfg.autoSendVersion === false)) { 93 //add version property to send to the server 94 cfg.content.version = Ozone.util.Transport.version; 95 } 96 97 // Convert state JSON object to string 98 if (cfg.content.state) { 99 cfg.content.state = Ozone.util.toString(cfg.content.state); 100 } 101 102 // Convert defaultSettings JSON object to string 103 if (cfg.content.defaultSettings) { 104 cfg.content.defaultSettings = Ozone.util.toString(cfg.content.defaultSettings); 105 } 106 107 var content = cfg.content; 108 109 var handleAs = 'json'; 110 if (cfg.handleAs != null) { 111 handleAs = cfg.handleAs; 112 } 113 114 // Use AJAX if we can 115 if (Ozone.util.isUrlLocal(cfg.url) && !cfg.forceXdomain) { 116 return owfdojo.xhr(methodToUse.toUpperCase(), { 117 url: cfg.url, 118 content: cfg.content, 119 preventCache: true, 120 sync: cfg.async == false? true : false, //defaults to false (not synchronous) 121 timeout : cfg.timeout ? cfg.timeout : 0, 122 headers: { 123 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 124 }, 125 load: function(response, ioArgs) { 126 if (Ozone.log) { 127 Ozone.log.getDefaultLogger().debug('Transport AJAX Return', response); 128 } 129 if (handleAs == 'json') { 130 try { 131 var json = Ozone.util.parseJson(response); 132 cfg.onSuccess(json); 133 } catch(e) { 134 cfg.onFailure(e.name + " : " + e.message); 135 } 136 } 137 else { 138 cfg.onSuccess(response); 139 } 140 }, 141 error: function(response, ioArgs) { 142 if (response.dojoType=='cancel') { return; } 143 // FF2 kills all AJAX requests when you refresh. When this happens, it sets the status code to 0 144 if (response.status != 0 ){ 145 if (cfg.ignoredErrorCodes != null && cfg.ignoredErrorCodes.length > 0 && owfdojo.indexOf(cfg.ignoredErrorCodes,response.status) > -1){ 146 cfg.onSuccess({}); 147 } 148 else { 149 cfg.onFailure(response.responseText, response.status); 150 } 151 } 152 } 153 }, hasBody); 154 } else { 155 // Use window.name transport 156 try { 157 var methodToUse = cfg.method; 158 if (methodToUse == "PUT" || methodToUse == "DELETE") 159 { 160 methodToUse = "POST"; 161 } 162 var deferred = owfdojox.io.windowName.send(methodToUse.toUpperCase(), { 163 url: cfg.url, 164 content: content, 165 preventCache: true, 166 timeout: cfg.timeout ? cfg.timeout : 20000, 167 load: 168 function(result) { 169 try { 170 // OWF-2750 - handle timeout errors which are already JSON objects 171 var json = null; 172 if (result && typeof(result) === 'string') { 173 json = Ozone.util.parseJson(result); 174 } 175 else { 176 json = result; 177 } 178 179 // OWF-2750 - detect a timeout error and return its message 180 if (json && json.message && json.message == 'Timeout') { 181 return cfg.onFailure('Error: Request timed out'); 182 } 183 184 if (json.status === 200) { 185 if (Ozone.log) { 186 Ozone.log.getDefaultLogger().debug('Transport AJAX Return', json.data); 187 } 188 if (handleAs == 'json') { 189 cfg.onSuccess(json.data); 190 } 191 else { 192 cfg.onSuccess(result); 193 } 194 } else if (json.status === 500 || json.status === 401) { 195 cfg.onFailure(json.data); 196 } 197 //if it is an error code we ignore than call onSuccess with empty data 198 else if (cfg.ignoredErrorCodes != null && cfg.ignoredErrorCodes.length > 0 && owfdojo.indexOf(cfg.ignoredErrorCodes,json.status) > -1){ 199 cfg.onSuccess({}); 200 } 201 else { 202 cfg.onFailure(json.data,json.status); 203 } 204 return json; 205 } 206 catch(e2) { 207 cfg.onFailure(e2.name + " : " + e2.message); 208 } 209 }, 210 error: 211 function(result){ 212 if (result.dojoType=='cancel') { return; } 213 if (result instanceof Error){ 214 cfg.onFailure(result.name + " : " + result.message); 215 } 216 else{ 217 cfg.onFailure(result); 218 } 219 } 220 }); 221 return deferred; 222 } 223 catch(e){ 224 cfg.onFailure(e.name + " : " + e.message); 225 } 226 } 227 228 }; 229 /** 230 * @private 231 * 232 * @params cfg.url - url of the request 233 * cfg.method - HTTP verb (only POST or GET, use _method = PUT or DELETE with a POST ) 234 * cfg.content - optional content to send with the request, ie {value: 'x', _method: 'PUT'} 235 * cfg.async - optional (default is true, asynchronous send, only applies to Ajax call) 236 * 237 * @returns void 238 * 239 * Static method. No callbacks are passed in, so you will not get a response. Useful for example in 240 * in 'beforeunload' when the the asyncronous callbacks are guaranteed to have the same 241 * javascript in the dom when they are firted 242 * 243 * 244 * This implementation uses the dojox.windowName hack for a remote server, 245 * but could be replaced with something else like JSONP if desired 246 */ 247 Ozone.util.Transport.sendAndForget = function(cfg) { 248 var cfg = cfg; 249 250 if (Ozone.log) { 251 Ozone.log.getDefaultLogger().debug('Transport SendAndForget', cfg.url, cfg.method, cfg.content); 252 } 253 254 var methodToUse = cfg.method; 255 if (methodToUse == "PUT" || methodToUse == "DELETE") 256 { 257 methodToUse = "POST"; 258 } 259 260 var hasBody = false; 261 if (methodToUse == "POST") { 262 hasBody = true; 263 } 264 265 if(cfg.content == null) { 266 cfg.content = {}; 267 } 268 269 //autoSendVersion to server default behavior is true 270 if (cfg.autoSendVersion === false) { 271 //add version property to send to the server 272 cfg.content.version = Ozone.util.Transport.version; 273 } 274 275 // Convert state JSON object to string 276 if (cfg.content.state) { 277 cfg.content.state = Ozone.util.toString(cfg.content.state); 278 } 279 280 var content = null; 281 if (methodToUse == "GET") { 282 content = owfdojo.objectToQuery(cfg.content); 283 } 284 else { 285 content = cfg.content; 286 } 287 288 // Use AJAX if we can 289 if (Ozone.util.isUrlLocal(cfg.url)) { 290 owfdojo.xhr(methodToUse.toUpperCase(), { 291 url: cfg.url, 292 content: cfg.content, 293 preventCache: true, 294 sync: cfg.async == false? false : true //defaults to true 295 }, hasBody); 296 } else { 297 // Use window.name transport 298 try { 299 var methodToUse = cfg.method; 300 if (methodToUse == "PUT" || methodToUse == "DELETE") 301 { 302 methodToUse = "POST"; 303 } 304 var deferred = owfdojox.io.windowName.send(methodToUse.toUpperCase(), { 305 url: cfg.url, 306 content: content, 307 preventCache: true 308 }); 309 } catch(e) { 310 if (!Ozone.Msg) 311 Ozone.util.ErrorDlg.show(Ozone.util.ErrorMessageString.sendAndForget,e.name + " : " + e.message,200,50); 312 else 313 Ozone.Msg.alert(Ozone.util.ErrorMessageString.sendAndForget,e.name + " : " + e.message); 314 } 315 } 316 }; 317 318 319 /** 320 * @private 321 * 322 * @params cfg.urls - Array of urls to try 323 * cfg.method - HTTP verb (only POST or GET, use _method = PUT or DELETE with a POST ) 324 * cfg.onSuccess - callback function to capture the success result 325 * cfg.onLastFailure - callback to execute if there is an error 326 * cfg.content - optional content to send with the request, ie {value: 'x', _method: 'PUT'} 327 * 328 * @returns void, use callbacks 329 * 330 * Static method. Allows the user to pass in an array of urls to try. The first one to return a response stops 331 * the processing. Uses the Ozone.util.Transport.send method. 332 */ 333 Ozone.util.Transport.sendToFirst = function(cfg) { 334 var u = cfg.urls.shift(); 335 336 if (u === undefined) { 337 if (cfg.onLastFailure !== undefined) { 338 cfg.onLastFailure(); 339 } 340 return; 341 } 342 343 var onThisFailure = function() { 344 Ozone.util.Transport.sendToFirst({ 345 urls:cfg.urls, 346 method:cfg.method, 347 onSuccess:cfg.onSuccess, 348 onLastFailure:cfg.onLastFailure, 349 content:cfg.content 350 }); 351 }; 352 353 Ozone.util.Transport.send({ 354 url:u, 355 method:cfg.method, 356 onSuccess:cfg.onSuccess, 357 onFailure:onThisFailure, 358 content:cfg.content 359 }); 360 }; 361