]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Request.js
initial commit
[syp.git] / openlayers / lib / OpenLayers / Request.js
1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2  * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3  * full text of the license. */
4
5 /**
6  * @requires OpenLayers/Events.js
7  */
8
9 /**
10  * Namespace: OpenLayers.Request
11  * The OpenLayers.Request namespace contains convenience methods for working
12  *     with XMLHttpRequests.  These methods work with a cross-browser
13  *     W3C compliant <OpenLayers.Request.XMLHttpRequest> class.
14  */
15 OpenLayers.Request = {
16     
17     /**
18      * Constant: DEFAULT_CONFIG
19      * {Object} Default configuration for all requests.
20      */
21     DEFAULT_CONFIG: {
22         method: "GET",
23         url: window.location.href,
24         async: true,
25         user: undefined,
26         password: undefined,
27         params: null,
28         proxy: OpenLayers.ProxyHost,
29         headers: {},
30         data: null,
31         callback: function() {},
32         success: null,
33         failure: null,
34         scope: null
35     },
36     
37     /**
38      * APIProperty: events
39      * {<OpenLayers.Events>} An events object that handles all 
40      *     events on the {<OpenLayers.Request>} object.
41      *
42      * All event listeners will receive an event object with three properties:
43      * request - {<OpenLayers.Request.XMLHttpRequest>} The request object.
44      * config - {Object} The config object sent to the specific request method.
45      * requestUrl - {String} The request url.
46      * 
47      * Supported event types:
48      * complete - Triggered when we have a response from the request, if a
49      *     listener returns false, no further response processing will take
50      *     place.
51      * success - Triggered when the HTTP response has a success code (200-299).
52      * failure - Triggered when the HTTP response does not have a success code.
53      */
54     events: new OpenLayers.Events(this, null, ["complete", "success", "failure"]),
55     
56     /**
57      * APIMethod: issue
58      * Create a new XMLHttpRequest object, open it, set any headers, bind
59      *     a callback to done state, and send any data.  It is recommended that
60      *     you use one <GET>, <POST>, <PUT>, <DELETE>, <OPTIONS>, or <HEAD>.
61      *     This method is only documented to provide detail on the configuration
62      *     options available to all request methods.
63      *
64      * Parameters:
65      * config - {Object} Object containing properties for configuring the
66      *     request.  Allowed configuration properties are described below.
67      *     This object is modified and should not be reused.
68      *
69      * Allowed config properties:
70      * method - {String} One of GET, POST, PUT, DELETE, HEAD, or
71      *     OPTIONS.  Default is GET.
72      * url - {String} URL for the request.
73      * async - {Boolean} Open an asynchronous request.  Default is true.
74      * user - {String} User for relevant authentication scheme.  Set
75      *     to null to clear current user.
76      * password - {String} Password for relevant authentication scheme.
77      *     Set to null to clear current password.
78      * proxy - {String} Optional proxy.  Defaults to
79      *     <OpenLayers.ProxyHost>.
80      * params - {Object} Any key:value pairs to be appended to the
81      *     url as a query string.  Assumes url doesn't already include a query
82      *     string or hash.  Typically, this is only appropriate for <GET>
83      *     requests where the query string will be appended to the url.
84      *     Parameter values that are arrays will be
85      *     concatenated with a comma (note that this goes against form-encoding)
86      *     as is done with <OpenLayers.Util.getParameterString>.
87      * headers - {Object} Object with header:value pairs to be set on
88      *     the request.
89      * data - {String | Document} Optional data to send with the request.
90      *     Typically, this is only used with <POST> and <PUT> requests.
91      *     Make sure to provide the appropriate "Content-Type" header for your
92      *     data.  For <POST> and <PUT> requests, the content type defaults to
93      *     "application-xml".  If your data is a different content type, or
94      *     if you are using a different HTTP method, set the "Content-Type"
95      *     header to match your data type.
96      * callback - {Function} Function to call when request is done.
97      *     To determine if the request failed, check request.status (200
98      *     indicates success).
99      * success - {Function} Optional function to call if request status is in
100      *     the 200s.  This will be called in addition to callback above and
101      *     would typically only be used as an alternative.
102      * failure - {Function} Optional function to call if request status is not
103      *     in the 200s.  This will be called in addition to callback above and
104      *     would typically only be used as an alternative.
105      * scope - {Object} If callback is a public method on some object,
106      *     set the scope to that object.
107      *
108      * Returns:
109      * {XMLHttpRequest} Request object.  To abort the request before a response
110      *     is received, call abort() on the request object.
111      */
112     issue: function(config) {        
113         // apply default config - proxy host may have changed
114         var defaultConfig = OpenLayers.Util.extend(
115             this.DEFAULT_CONFIG,
116             {proxy: OpenLayers.ProxyHost}
117         );
118         config = OpenLayers.Util.applyDefaults(config, defaultConfig);
119
120         // create request, open, and set headers
121         var request = new OpenLayers.Request.XMLHttpRequest();
122         var url = config.url;
123         if(config.params) {
124             var paramString = OpenLayers.Util.getParameterString(config.params);
125             if(paramString.length > 0) {
126                 var separator = (url.indexOf('?') > -1) ? '&' : '?';
127                 url += separator + paramString;
128             }
129         }
130         if(config.proxy && (url.indexOf("http") == 0)) {
131             url = config.proxy + encodeURIComponent(url);
132         }
133         request.open(
134             config.method, url, config.async, config.user, config.password
135         );
136         for(var header in config.headers) {
137             request.setRequestHeader(header, config.headers[header]);
138         }
139
140         // bind callbacks to readyState 4 (done)
141         var complete = (config.scope) ?
142             OpenLayers.Function.bind(config.callback, config.scope) :
143             config.callback;
144         
145         // optional success callback
146         var success;
147         if(config.success) {
148             success = (config.scope) ?
149                 OpenLayers.Function.bind(config.success, config.scope) :
150                 config.success;
151         }
152
153         // optional failure callback
154         var failure;
155         if(config.failure) {
156             failure = (config.scope) ?
157                 OpenLayers.Function.bind(config.failure, config.scope) :
158                 config.failure;
159         }
160         
161         var events = this.events;
162          
163         request.onreadystatechange = function() {
164             if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {
165                 var proceed = events.triggerEvent(
166                     "complete",
167                     {request: request, config: config, requestUrl: url}
168                 );
169                 if(proceed !== false) {
170                     complete(request);
171                     if (!request.status || (request.status >= 200 && request.status < 300)) {
172                         events.triggerEvent(
173                             "success",
174                             {request: request, config: config, requestUrl: url}
175                         );
176                         if(success) {
177                             success(request);
178                         }
179                     }
180                     if(request.status && (request.status < 200 || request.status >= 300)) {                    
181                         events.triggerEvent(
182                             "failure",
183                             {request: request, config: config, requestUrl: url}
184                         );
185                         if(failure) {
186                             failure(request);
187                         }
188                     }
189                 }
190             }
191         };
192         
193         // send request (optionally with data) and return
194         // call in a timeout for asynchronous requests so the return is
195         // available before readyState == 4 for cached docs
196         if(config.async === false) {
197             request.send(config.data);
198         } else {
199             window.setTimeout(function(){
200                 request.send(config.data);
201             }, 0);
202         }
203         return request;
204     },
205     
206     /**
207      * APIMethod: GET
208      * Send an HTTP GET request.  Additional configuration properties are
209      *     documented in the <issue> method, with the method property set
210      *     to GET.
211      *
212      * Parameters:
213      * config - {Object} Object with properties for configuring the request.
214      *     See the <issue> method for documentation of allowed properties.
215      *     This object is modified and should not be reused.
216      * 
217      * Returns:
218      * {XMLHttpRequest} Request object.
219      */
220     GET: function(config) {
221         config = OpenLayers.Util.extend(config, {method: "GET"});
222         return OpenLayers.Request.issue(config);
223     },
224     
225     /**
226      * APIMethod: POST
227      * Send a POST request.  Additional configuration properties are
228      *     documented in the <issue> method, with the method property set
229      *     to POST and "Content-Type" header set to "application/xml".
230      *
231      * Parameters:
232      * config - {Object} Object with properties for configuring the request.
233      *     See the <issue> method for documentation of allowed properties.  The
234      *     default "Content-Type" header will be set to "application-xml" if
235      *     none is provided.  This object is modified and should not be reused.
236      * 
237      * Returns:
238      * {XMLHttpRequest} Request object.
239      */
240     POST: function(config) {
241         config = OpenLayers.Util.extend(config, {method: "POST"});
242         // set content type to application/xml if it isn't already set
243         config.headers = config.headers ? config.headers : {};
244         if(!("CONTENT-TYPE" in OpenLayers.Util.upperCaseObject(config.headers))) {
245             config.headers["Content-Type"] = "application/xml";
246         }
247         return OpenLayers.Request.issue(config);
248     },
249     
250     /**
251      * APIMethod: PUT
252      * Send an HTTP PUT request.  Additional configuration properties are
253      *     documented in the <issue> method, with the method property set
254      *     to PUT and "Content-Type" header set to "application/xml".
255      *
256      * Parameters:
257      * config - {Object} Object with properties for configuring the request.
258      *     See the <issue> method for documentation of allowed properties.  The
259      *     default "Content-Type" header will be set to "application-xml" if
260      *     none is provided.  This object is modified and should not be reused.
261      * 
262      * Returns:
263      * {XMLHttpRequest} Request object.
264      */
265     PUT: function(config) {
266         config = OpenLayers.Util.extend(config, {method: "PUT"});
267         // set content type to application/xml if it isn't already set
268         config.headers = config.headers ? config.headers : {};
269         if(!("CONTENT-TYPE" in OpenLayers.Util.upperCaseObject(config.headers))) {
270             config.headers["Content-Type"] = "application/xml";
271         }
272         return OpenLayers.Request.issue(config);
273     },
274     
275     /**
276      * APIMethod: DELETE
277      * Send an HTTP DELETE request.  Additional configuration properties are
278      *     documented in the <issue> method, with the method property set
279      *     to DELETE.
280      *
281      * Parameters:
282      * config - {Object} Object with properties for configuring the request.
283      *     See the <issue> method for documentation of allowed properties.
284      *     This object is modified and should not be reused.
285      * 
286      * Returns:
287      * {XMLHttpRequest} Request object.
288      */
289     DELETE: function(config) {
290         config = OpenLayers.Util.extend(config, {method: "DELETE"});
291         return OpenLayers.Request.issue(config);
292     },
293   
294     /**
295      * APIMethod: HEAD
296      * Send an HTTP HEAD request.  Additional configuration properties are
297      *     documented in the <issue> method, with the method property set
298      *     to HEAD.
299      *
300      * Parameters:
301      * config - {Object} Object with properties for configuring the request.
302      *     See the <issue> method for documentation of allowed properties.
303      *     This object is modified and should not be reused.
304      * 
305      * Returns:
306      * {XMLHttpRequest} Request object.
307      */
308     HEAD: function(config) {
309         config = OpenLayers.Util.extend(config, {method: "HEAD"});
310         return OpenLayers.Request.issue(config);
311     },
312     
313     /**
314      * APIMethod: OPTIONS
315      * Send an HTTP OPTIONS request.  Additional configuration properties are
316      *     documented in the <issue> method, with the method property set
317      *     to OPTIONS.
318      *
319      * Parameters:
320      * config - {Object} Object with properties for configuring the request.
321      *     See the <issue> method for documentation of allowed properties.
322      *     This object is modified and should not be reused.
323      * 
324      * Returns:
325      * {XMLHttpRequest} Request object.
326      */
327     OPTIONS: function(config) {
328         config = OpenLayers.Util.extend(config, {method: "OPTIONS"});
329         return OpenLayers.Request.issue(config);
330     }
331
332 };