Ticket #1170: patch_ajax.diff
| File patch_ajax.diff, 20.2 kB (added by pgiraud, 1 year ago) |
|---|
-
tests/manual/ajax.txt
old new -
tests/manual/ajax.html
old new 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title>Draw Feature Acceptance Test</title> 4 <style type="text/css"> 5 6 body { 7 font-size: 0.8em; 8 } 9 p { 10 padding-top: 1em; 11 } 12 13 .buttons { 14 margin: 1em; 15 float: left; 16 } 17 18 </style> 19 20 <script src="../../lib/OpenLayers.js"></script> 21 <script type="text/javascript"> 22 var url = "ajax.txt"; 23 function sendSynchronous(){ 24 var request = new OpenLayers.Ajax.Request(url, { 25 onComplete: function() { 26 document.getElementById('send_sync').value += 'request completed\n'; 27 } 28 }); 29 document.getElementById('send_sync').value += 'other processing\n'; 30 } 31 function sendAsynchronous(){ 32 var request = new OpenLayers.Ajax.Request(url, { 33 'asynchronous': false, 34 onComplete: function() { 35 document.getElementById('send_sync').value += 'request completed\n'; 36 } 37 }); 38 document.getElementById('send_sync').value += 'other processing\n'; 39 } 40 function sendAndAbort(){ 41 var request = new OpenLayers.Ajax.Request(url, { 42 onComplete: function(request) { 43 if (request.responseText == '') { 44 document.getElementById('send_sync').value += 'request aborted\n'; 45 } 46 } 47 }); 48 request.transport.abort(); 49 document.getElementById('send_sync').value += 'other processing\n'; 50 } 51 52 </script> 53 </head> 54 <body > 55 <div class="buttons"> 56 <button onclick="sendSynchronous()">Send an synchronous Ajax request</button><br /> 57 <button onclick="sendAsynchronous()">Send an asynchronous Ajax request</button><br /> 58 <button onclick="sendAndAbort()">Send a request and abort it</button><br /> 59 <textarea id="send_sync" rows="6"></textarea><br /> 60 <button onclick="document.getElementById('send_sync').value = ''">Clear</button> 61 </div> 62 <p><b></b></p> 63 <p>Clicking on the different buttons should give the following results in the textarea below :</p> 64 <ul> 65 <li>"other processing" then "request completed"</li> 66 <li>"request completed" then "other processing"</li> 67 <li>"request aborted" then "other processing"</li> 68 </ul> 69 </body> 70 </html> -
lib/OpenLayers/Ajax.js
old new 135 135 */ 136 136 getTransport: function() { 137 137 return OpenLayers.Util.Try( 138 function() {return new XMLHttpRequest();}, 138 139 function() {return new ActiveXObject('Msxml2.XMLHTTP');}, 139 function() {return new ActiveXObject('Microsoft.XMLHTTP');}, 140 function() {return new XMLHttpRequest();} 140 function() {return new ActiveXObject('Microsoft.XMLHTTP');} 141 141 ) || false; 142 142 }, 143 143 … … 167 167 * responderToAdd - {?} 168 168 */ 169 169 register: function(responderToAdd) { 170 for (var i = 0; i < this.responders.length; i++){171 if (responderToAdd == this.responders[i]){172 return;173 }174 }175 this.responders.push(responderToAdd);170 for (var i = 0; i < this.responders.length; i++){ 171 if (responderToAdd == this.responders[i]){ 172 return; 173 } 174 } 175 this.responders.push(responderToAdd); 176 176 }, 177 177 178 178 /** 179 * Method: unregister 180 * 181 * Parameters: 182 * responderToRemove - {?} 183 */ 184 unregister: function(responderToRemove) { 185 OpenLayers.Util.removeItem(this.reponders, responderToRemove); 186 }, 187 188 /** 179 189 * Method: dispatch 180 190 * 181 191 * Parameters: 182 192 * callback - {?} 183 193 * request - {?} 184 194 * transport - {?} 185 * json - {?}186 195 */ 187 dispatch: function(callback, request, transport , json) {196 dispatch: function(callback, request, transport) { 188 197 var responder; 189 198 for (var i = 0; i < this.responders.length; i++) { 190 199 responder = this.responders[i]; … … 193 202 typeof responder[callback] == 'function') { 194 203 try { 195 204 responder[callback].apply(responder, 196 [request, transport , json]);205 [request, transport]); 197 206 } catch (e) {} 198 207 } 199 208 } … … 217 226 }); 218 227 219 228 /** 220 * Namespace: OpenLayers.Ajax.Base 221 * {Object} 229 * Class: OpenLayers.Ajax.Base 222 230 */ 223 OpenLayers.Ajax.Base = function() {}; 224 OpenLayers.Ajax.Base.prototype = { 225 231 OpenLayers.Ajax.Base = OpenLayers.Class({ 232 226 233 /** 227 * Function: setOptions234 * Constructor: OpenLayers.Ajax.Base 228 235 * 229 * Parameters: 236 * Parameters: 230 237 * options - {Object} 231 238 */ 232 setOptions: function(options) {239 initialize: function(options) { 233 240 this.options = { 234 'method': 'post', 235 'asynchronous': true, 236 'parameters': '' 241 method: 'post', 242 asynchronous: true, 243 contentType: 'application/x-www-form-urlencoded', 244 encoding: 'UTF-8', 245 parameters: '' 237 246 }; 238 247 OpenLayers.Util.extend(this.options, options || {}); 239 }, 240 241 /** 242 * Function: responseIsSuccess 243 * 244 * Returns: 245 * {Boolean} 246 */ 247 responseIsSuccess: function() { 248 return this.transport.status == undefined || 249 this.transport.status == 0 || 250 (this.transport.status >= 200 && this.transport.status < 300); 251 }, 252 253 /** 254 * Function: responseIsFailure 255 * 256 * Returns: 257 * {Boolean} 258 */ 259 responseIsFailure: function() { 260 return !this.responseIsSuccess(); 248 249 this.options.method = this.options.method.toLowerCase(); 250 251 if (typeof this.options.parameters == 'string') { 252 this.options.parameters = 253 OpenLayers.Util.getParameters(this.options.parameters); 254 } 261 255 } 262 } ;256 }); 263 257 264 265 258 /** 266 259 * Class: OpenLayers.Ajax.Request 267 260 * … … 269 262 * - <OpenLayers.Ajax.Base> 270 263 */ 271 264 OpenLayers.Ajax.Request = OpenLayers.Class(OpenLayers.Ajax.Base, { 265 266 /** 267 * Property: _complete 268 * 269 * {Boolean} 270 */ 271 _complete: false, 272 272 273 /**274 * Constructor: OpenLayers.Ajax.Request275 *276 * Parameters:277 * url - {String}278 * options - {Object}279 */273 /** 274 * Constructor: OpenLayers.Ajax.Request 275 * 276 * Parameters: 277 * url - {String} 278 * options - {Object} 279 */ 280 280 initialize: function(url, options) { 281 OpenLayers.Ajax.Base.prototype.initialize.apply(this, [options]); 282 281 283 this.transport = OpenLayers.Ajax.getTransport(); 282 this.setOptions(options);283 284 this.request(url); 284 285 }, 285 286 … … 290 291 * url - {String} 291 292 */ 292 293 request: function(url) { 293 var parameters = this.options.parameters || ''; 294 if (parameters.length > 0) { 295 parameters += '&_='; 294 this.url = url; 295 this.method = this.options.method; 296 var params = OpenLayers.Util.extend({}, this.options.parameters); 297 298 if (this.method != 'get' && this.method != 'post') { 299 // simulate other verbs over post 300 params['_method'] = this.method; 301 this.method = 'post'; 296 302 } 303 304 this.parameters = params; 305 306 if (params = OpenLayers.Util.getParameterString(params)) { 307 // when GET, append parameters to URL 308 if (this.method == 'get') { 309 this.url += ((this.url.indexOf('?') > -1) ? '&' : '?') + params; 310 } else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { 311 params += '&_='; 312 } 313 } 297 314 try { 298 this.url = url;299 if (this.options. method == 'get' && parameters.length > 0) {300 this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;315 var response = new OpenLayers.Ajax.Response(this); 316 if (this.options.onCreate) { 317 this.options.onCreate(response); 301 318 } 302 319 303 320 OpenLayers.Ajax.Responders.dispatch('onCreate', 304 321 this, 305 this.transport);322 response); 306 323 307 this.transport.open(this. options.method,324 this.transport.open(this.method.toUpperCase(), 308 325 this.url, 309 326 this.options.asynchronous); 310 327 311 328 if (this.options.asynchronous) { 312 setTimeout(OpenLayers.Function.bind(313 (function() {this.respondToReadyState(1);}),this), 10314 );329 window.setTimeout( 330 OpenLayers.Function.bind(this.respondToReadyState, this), 331 1000); 315 332 } 316 333 317 334 this.transport.onreadystatechange = 318 335 OpenLayers.Function.bind(this.onStateChange, this); 319 336 this.setRequestHeaders(); 320 337 321 var body = this.options.postBody ? this.options.postBody322 : parameters;323 this.transport.send(this. options.method == 'post' ? body : null);338 this.body = this.method == 'post' ? 339 (this.options.postBody || params) : null; 340 this.transport.send(this.body); 324 341 325 342 // Force Firefox to handle ready state 4 for synchronous requests 326 343 if (!this.options.asynchronous && 327 344 this.transport.overrideMimeType) { 328 329 345 this.onStateChange(); 330 346 } 331 332 347 } catch (e) { 333 348 this.dispatchException(e); 334 349 } 335 350 }, 351 352 /** 353 * Method: onStateChange 354 */ 355 onStateChange: function() { 356 var readyState = this.transport.readyState; 357 if (readyState > 1 && !((readyState == 4) && this._complete)) { 358 this.respondToReadyState(this.transport.readyState); 359 } 360 }, 336 361 337 362 /** 338 363 * Method: setRequestHeaders 339 364 */ 340 365 setRequestHeaders: function() { 341 var requestHeaders = [ 342 'X-Requested-With', 343 'XMLHttpRequest', 344 'X-Prototype-Version', 345 'OpenLayers' 346 ]; 366 var headers = { 367 'X-Requested-With': 'XMLHttpRequest', 368 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*', 369 'OpenLayers': true 370 }; 371 372 if (this.method == 'post') { 373 headers['Content-type'] = this.options.contentType + 374 (this.options.encoding ? '; charset=' + this.options.encoding : ''); 347 375 348 if (this.options.method == 'post' && !this.options.postBody) { 349 requestHeaders.push('Content-type', 350 'application/x-www-form-urlencoded'); 351 352 // Force "Connection: close" for Mozilla browsers to work around 353 // a bug where XMLHttpReqeuest sends an incorrect Content-length 354 // header. See Mozilla Bugzilla #246651. 355 if (this.transport.overrideMimeType) { 356 requestHeaders.push('Connection', 'close'); 376 /* Force "Connection: close" for older Mozilla browsers to work 377 * around a bug where XMLHttpRequest sends an incorrect 378 * Content-length header. See Mozilla Bugzilla #246651. 379 */ 380 if (this.transport.overrideMimeType && 381 (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) { 382 headers['Connection'] = 'close'; 357 383 } 358 384 } 359 360 if (this.options.requestHeaders) { 361 requestHeaders.push.apply(requestHeaders, 362 this.options.requestHeaders); 385 // user-defined headers 386 if (typeof this.options.requestHeaders == 'object') { 387 var extras = this.options.requestHeaders; 388 389 if (typeof extra.push == 'function') { 390 for (var i = 0, length = extras.length; i < length; i += 2) { 391 headers[extras[i]] = extras[i+1]; 392 } 393 } else { 394 for (var i in extras) { 395 headers[i] = pair[i]; 396 } 397 } 363 398 } 364 365 for (var i = 0; i < requestHeaders.length; i += 2) { 366 this.transport.setRequestHeader(requestHeaders[i], 367 requestHeaders[i+1]); 399 400 for (var name in headers) { 401 this.transport.setRequestHeader(name, headers[name]); 368 402 } 369 403 }, 370 404 371 405 /** 372 * Method: onStateChange 373 */ 374 onStateChange: function() { 375 var readyState = this.transport.readyState; 376 if (readyState != 1) { 377 this.respondToReadyState(this.transport.readyState); 378 } 379 }, 380 381 /** 382 * Method: header 383 * 406 * Method: success 407 * 384 408 * Returns: 385 * { ?}409 * {Boolean} - 386 410 */ 387 header: function(name) { 388 try { 389 return this.transport.getResponseHeader(name); 390 } catch (e) {} 411 success: function() { 412 var status = this.getStatus(); 413 return !status || (status >=200 && status < 300); 391 414 }, 392 393 /** 394 * Method: evalJSON395 * 415 416 /** 417 * Method: getStatus 418 * 396 419 * Returns: 397 * { ?}420 * {Integer} - Status 398 421 */ 399 evalJSON: function() {422 getStatus: function() { 400 423 try { 401 return eval(this.header('X-JSON')); 402 } catch (e) {} 403 }, 404 405 /** 406 * Method: evalResponse 407 * 408 * Returns: 409 * {?} 410 */ 411 evalResponse: function() { 412 try { 413 return eval(this.transport.responseText); 424 return this.transport.status || 0; 414 425 } catch (e) { 415 this.dispatchException(e);426 return 0 416 427 } 417 428 }, 418 429 … … 423 434 * readyState - {?} 424 435 */ 425 436 respondToReadyState: function(readyState) { 426 var event= OpenLayers.Ajax.Request.Events[readyState];427 var transport = this.transport, json = this.evalJSON();437 var state = OpenLayers.Ajax.Request.Events[readyState]; 438 var response = new OpenLayers.Ajax.Response(this); 428 439 429 if ( event== 'Complete') {440 if (state == 'Complete') { 430 441 try { 431 var responseSuccess = this.responseIsSuccess() ? 'Success' 432 : 'Failure'; 433 434 (this.options['on' + this.transport.status] || 435 this.options['on' + responseSuccess] || 436 OpenLayers.Ajax.emptyFunction)(transport, json); 442 this._complete = true; 443 (this.options['on' + response.status] || 444 this.options['on' + (this.success() ? 'Success' : 'Failure')] || 445 OpenLayers.Ajax.emptyFunction)(response); 437 446 } catch (e) { 438 447 this.dispatchException(e); 439 448 } 440 449 441 var contentType = this.header('Content-type') || ''; 442 if (contentType.match(/^text\/javascript/i)) { 443 this.evalResponse(); 444 } 450 var contentType = response.getHeader('Content-type'); 445 451 } 446 452 447 453 try { 448 (this.options['on' + event] ||449 OpenLayers.Ajax.emptyFunction)( transport, json);450 OpenLayers.Ajax.Responders.dispatch('on' + event,454 (this.options['on' + state] || 455 OpenLayers.Ajax.emptyFunction)(response); 456 OpenLayers.Ajax.Responders.dispatch('on' + state, 451 457 this, 452 transport, 453 json); 458 response); 454 459 } catch (e) { 455 460 this.dispatchException(e); 456 461 } 457 462 458 // Avoid memory leak in MSIE: clean up the oncomplete event handler459 if (event == 'Complete') {463 if (state == 'Complete') { 464 // avoid memory leak in MSIE: clean up 460 465 this.transport.onreadystatechange = OpenLayers.Ajax.emptyFunction; 461 466 } 462 467 }, 468 469 /** 470 * Method: getHeader 471 * 472 * Parameters: 473 * name - {String} Header name 474 * 475 * Returns: 476 * {?} - response header for the given name 477 */ 478 getHeader: function(name) { 479 try { 480 return this.transport.getResponseHeader(name); 481 } catch (e) { 482 return null 483 } 484 }, 463 485 464 486 /** 465 487 * Method: dispatchException … … 468 490 * exception - {?} 469 491 */ 470 492 dispatchException: function(exception) { 471 if (this.options.onException) { 472 this.options.onException(this, exception); 473 } else { 474 // if we get here, Responders.dispatch('onException') will never 475 // be called. too bad. we should probably take out the Responders 476 // stuff anyway. 477 throw exception; 478 } 493 (this.options.onException || 494 OpenLayers.Ajax.emptyFunction)(this, exception); 479 495 OpenLayers.Ajax.Responders.dispatch('onException', this, exception); 480 496 } 481 482 497 }); 483 498 484 499 /** … … 489 504 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 490 505 491 506 /** 507 * Class: OpenLayers.Ajax.Request 508 * 509 * Inherit: 510 * - <OpenLayers.Ajax.Base> 511 */ 512 OpenLayers.Ajax.Response = OpenLayers.Class({ 513 514 /** 515 * Property: status 516 * 517 * {Integer} 518 */ 519 status: 0, 520 521 522 /** 523 * Property: statusText 524 * 525 * {String} 526 */ 527 statusText: '', 528 529 /** 530 * Constructor: OpenLayers.Ajax.Response 531 * 532 * Parameters: 533 * request - {Object} 534 */ 535 initialize: function(request) { 536 this.request = request; 537 var transport = this.transport = request.transport, 538 readyState = this.readyState = transport.readyState; 539 540 if ((readyState > 2 && 541 !(!!(window.attachEvent && !window.opera))) || 542 readyState == 4) { 543 this.status = this.getStatus(); 544 this.statusText = this.getStatusText(); 545 this.responseText = transport.responseText == null ? 546 '' : String(transport.responseText); 547 } 548 549 if(readyState == 4) { 550 var xml = transport.responseXML; 551 this.responseXML = xml === undefined ? null : xml; 552 } 553 }, 554 555 /** 556 * Method: getStatus 557 */ 558 getStatus: OpenLayers.Ajax.Request.prototype.getStatus, 559 560 /** 561 * Method: getStatustext 562 * 563 * Returns: 564 * {String} - statusText 565 */ 566 getStatusText: function() { 567 try { 568 return this.transport.statusText || ''; 569 } catch (e) { 570 return ''; 571 } 572 }, 573 574 /** 575 * Method: getHeader 576 */ 577 getHeader: OpenLayers.Ajax.Request.prototype.getHeader, 578 579 /** 580 * Method: getResponseHeader 581 * 582 * Returns: 583 * {?} - response header for given name 584 */ 585 getResponseHeader: function(name) { 586 return this.transport.getResponseHeader(name); 587 } 588 }); 589 590 591 /** 492 592 * Function: getElementsByTagNameNS 493 593 * 494 594 * Parameters:
