/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for * full list of contributors). Published under the Clear BSD license. * See http://svn.openlayers.org/trunk/openlayers/license.txt for the * full text of the license. */ /** * @requires OpenLayers/Events.js */ /** * Namespace: OpenLayers.Request * The OpenLayers.Request namespace contains convenience methods for working * with XMLHttpRequests. These methods work with a cross-browser * W3C compliant class. */ OpenLayers.Request = { /** * Constant: DEFAULT_CONFIG * {Object} Default configuration for all requests. */ DEFAULT_CONFIG: { method: "GET", url: window.location.href, async: true, user: undefined, password: undefined, params: null, proxy: OpenLayers.ProxyHost, headers: {}, data: null, callback: function() {}, success: null, failure: null, scope: null }, /** * APIProperty: events * {} An events object that handles all * events on the {} object. * * All event listeners will receive an event object with three properties: * request - {} The request object. * config - {Object} The config object sent to the specific request method. * requestUrl - {String} The request url. * * Supported event types: * complete - Triggered when we have a response from the request, if a * listener returns false, no further response processing will take * place. * success - Triggered when the HTTP response has a success code (200-299). * failure - Triggered when the HTTP response does not have a success code. */ events: new OpenLayers.Events(this, null, ["complete", "success", "failure"]), /** * APIMethod: issue * Create a new XMLHttpRequest object, open it, set any headers, bind * a callback to done state, and send any data. It is recommended that * you use one , , , , , or . * This method is only documented to provide detail on the configuration * options available to all request methods. * * Parameters: * config - {Object} Object containing properties for configuring the * request. Allowed configuration properties are described below. * This object is modified and should not be reused. * * Allowed config properties: * method - {String} One of GET, POST, PUT, DELETE, HEAD, or * OPTIONS. Default is GET. * url - {String} URL for the request. * async - {Boolean} Open an asynchronous request. Default is true. * user - {String} User for relevant authentication scheme. Set * to null to clear current user. * password - {String} Password for relevant authentication scheme. * Set to null to clear current password. * proxy - {String} Optional proxy. Defaults to * . * params - {Object} Any key:value pairs to be appended to the * url as a query string. Assumes url doesn't already include a query * string or hash. Typically, this is only appropriate for * requests where the query string will be appended to the url. * Parameter values that are arrays will be * concatenated with a comma (note that this goes against form-encoding) * as is done with . * headers - {Object} Object with header:value pairs to be set on * the request. * data - {String | Document} Optional data to send with the request. * Typically, this is only used with and requests. * Make sure to provide the appropriate "Content-Type" header for your * data. For and requests, the content type defaults to * "application-xml". If your data is a different content type, or * if you are using a different HTTP method, set the "Content-Type" * header to match your data type. * callback - {Function} Function to call when request is done. * To determine if the request failed, check request.status (200 * indicates success). * success - {Function} Optional function to call if request status is in * the 200s. This will be called in addition to callback above and * would typically only be used as an alternative. * failure - {Function} Optional function to call if request status is not * in the 200s. This will be called in addition to callback above and * would typically only be used as an alternative. * scope - {Object} If callback is a public method on some object, * set the scope to that object. * * Returns: * {XMLHttpRequest} Request object. To abort the request before a response * is received, call abort() on the request object. */ issue: function(config) { // apply default config - proxy host may have changed var defaultConfig = OpenLayers.Util.extend( this.DEFAULT_CONFIG, {proxy: OpenLayers.ProxyHost} ); config = OpenLayers.Util.applyDefaults(config, defaultConfig); // create request, open, and set headers var request = new OpenLayers.Request.XMLHttpRequest(); var url = config.url; if(config.params) { var paramString = OpenLayers.Util.getParameterString(config.params); if(paramString.length > 0) { var separator = (url.indexOf('?') > -1) ? '&' : '?'; url += separator + paramString; } } if(config.proxy && (url.indexOf("http") == 0)) { if(typeof config.proxy == "function") { url = config.proxy(url); } else { url = config.proxy + encodeURIComponent(url); } } request.open( config.method, url, config.async, config.user, config.password ); for(var header in config.headers) { request.setRequestHeader(header, config.headers[header]); } var events = this.events; // we want to execute runCallbacks with "this" as the // execution scope var self = this; request.onreadystatechange = function() { if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) { var proceed = events.triggerEvent( "complete", {request: request, config: config, requestUrl: url} ); if(proceed !== false) { self.runCallbacks( {request: request, config: config, requestUrl: url} ); } } }; // send request (optionally with data) and return // call in a timeout for asynchronous requests so the return is // available before readyState == 4 for cached docs if(config.async === false) { request.send(config.data); } else { window.setTimeout(function(){ if (request._aborted !== true) { request.send(config.data); } }, 0); } return request; }, /** * Method: runCallbacks * Calls the complete, success and failure callbacks. Application * can listen to the "complete" event, have the listener * display a confirm window and always return false, and * execute OpenLayers.Request.runCallbacks if the user * hits "yes" in the confirm window. * * Parameters: * options - {Object} Hash containing request, config and requestUrl keys */ runCallbacks: function(options) { var request = options.request; var config = options.config; // bind callbacks to readyState 4 (done) var complete = (config.scope) ? OpenLayers.Function.bind(config.callback, config.scope) : config.callback; // optional success callback var success; if(config.success) { success = (config.scope) ? OpenLayers.Function.bind(config.success, config.scope) : config.success; } // optional failure callback var failure; if(config.failure) { failure = (config.scope) ? OpenLayers.Function.bind(config.failure, config.scope) : config.failure; } complete(request); if (!request.status || (request.status >= 200 && request.status < 300)) { this.events.triggerEvent("success", options); if(success) { success(request); } } if(request.status && (request.status < 200 || request.status >= 300)) { this.events.triggerEvent("failure", options); if(failure) { failure(request); } } }, /** * APIMethod: GET * Send an HTTP GET request. Additional configuration properties are * documented in the method, with the method property set * to GET. * * Parameters: * config - {Object} Object with properties for configuring the request. * See the method for documentation of allowed properties. * This object is modified and should not be reused. * * Returns: * {XMLHttpRequest} Request object. */ GET: function(config) { config = OpenLayers.Util.extend(config, {method: "GET"}); return OpenLayers.Request.issue(config); }, /** * APIMethod: POST * Send a POST request. Additional configuration properties are * documented in the method, with the method property set * to POST and "Content-Type" header set to "application/xml". * * Parameters: * config - {Object} Object with properties for configuring the request. * See the method for documentation of allowed properties. The * default "Content-Type" header will be set to "application-xml" if * none is provided. This object is modified and should not be reused. * * Returns: * {XMLHttpRequest} Request object. */ POST: function(config) { config = OpenLayers.Util.extend(config, {method: "POST"}); // set content type to application/xml if it isn't already set config.headers = config.headers ? config.headers : {}; if(!("CONTENT-TYPE" in OpenLayers.Util.upperCaseObject(config.headers))) { config.headers["Content-Type"] = "application/xml"; } return OpenLayers.Request.issue(config); }, /** * APIMethod: PUT * Send an HTTP PUT request. Additional configuration properties are * documented in the method, with the method property set * to PUT and "Content-Type" header set to "application/xml". * * Parameters: * config - {Object} Object with properties for configuring the request. * See the method for documentation of allowed properties. The * default "Content-Type" header will be set to "application-xml" if * none is provided. This object is modified and should not be reused. * * Returns: * {XMLHttpRequest} Request object. */ PUT: function(config) { config = OpenLayers.Util.extend(config, {method: "PUT"}); // set content type to application/xml if it isn't already set config.headers = config.headers ? config.headers : {}; if(!("CONTENT-TYPE" in OpenLayers.Util.upperCaseObject(config.headers))) { config.headers["Content-Type"] = "application/xml"; } return OpenLayers.Request.issue(config); }, /** * APIMethod: DELETE * Send an HTTP DELETE request. Additional configuration properties are * documented in the method, with the method property set * to DELETE. * * Parameters: * config - {Object} Object with properties for configuring the request. * See the method for documentation of allowed properties. * This object is modified and should not be reused. * * Returns: * {XMLHttpRequest} Request object. */ DELETE: function(config) { config = OpenLayers.Util.extend(config, {method: "DELETE"}); return OpenLayers.Request.issue(config); }, /** * APIMethod: HEAD * Send an HTTP HEAD request. Additional configuration properties are * documented in the method, with the method property set * to HEAD. * * Parameters: * config - {Object} Object with properties for configuring the request. * See the method for documentation of allowed properties. * This object is modified and should not be reused. * * Returns: * {XMLHttpRequest} Request object. */ HEAD: function(config) { config = OpenLayers.Util.extend(config, {method: "HEAD"}); return OpenLayers.Request.issue(config); }, /** * APIMethod: OPTIONS * Send an HTTP OPTIONS request. Additional configuration properties are * documented in the method, with the method property set * to OPTIONS. * * Parameters: * config - {Object} Object with properties for configuring the request. * See the method for documentation of allowed properties. * This object is modified and should not be reused. * * Returns: * {XMLHttpRequest} Request object. */ OPTIONS: function(config) { config = OpenLayers.Util.extend(config, {method: "OPTIONS"}); return OpenLayers.Request.issue(config); } };