source: Dev/branches/rest-dojo-ui/client/dojox/io/xhrPlugins.js @ 274

Last change on this file since 274 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 5.8 KB
Line 
1define(["dojo/_base/kernel", "dojo/_base/xhr", "dojo/AdapterRegistry"], function(dojo, xhr, AdapterRegistry){
2        dojo.getObject("io.xhrPlugins", true, dojox);
3
4        var registry;
5        var plainXhr;
6        function getPlainXhr(){
7                return plainXhr = dojox.io.xhrPlugins.plainXhr = plainXhr || dojo._defaultXhr || xhr;
8        }
9        dojox.io.xhrPlugins.register = function(){
10                //      summary:
11                //              overrides the default xhr handler to implement a registry of
12                //              xhr handlers
13                var plainXhr = getPlainXhr();
14                if(!registry){
15                        registry = new AdapterRegistry();
16                        // replaces the default xhr() method. Can we just use connect() instead?
17                        dojo[dojo._defaultXhr ? "_defaultXhr" : "xhr"] = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
18                                return registry.match.apply(registry,arguments);
19                        };
20                        registry.register(
21                                "xhr",
22                                function(method,args){
23                                        if(!args.url.match(/^\w*:\/\//)){
24                                                // if it is not an absolute url (or relative to the
25                                                // protocol) we can use this plain XHR
26                                                return true;
27                                        }
28                                        var root = window.location.href.match(/^.*?\/\/.*?\//)[0];
29                                        return args.url.substring(0, root.length) == root; // or check to see if we have the same path
30                                },
31                                plainXhr
32                        );
33                }
34                return registry.register.apply(registry, arguments);
35        };
36        dojox.io.xhrPlugins.addProxy = function(proxyUrl){
37                //      summary:
38                //              adds a server side proxy xhr handler for cross-site URLs
39                //      proxyUrl:
40                //              This is URL to send the requests to.
41                //      example:
42                //              Define a proxy:
43                //      |       dojox.io.xhrPlugins.addProxy("/proxy?url=");
44                //              And then when you call:
45                //      |       dojo.xhr("GET",{url:"http://othersite.com/file"});
46                //              It would result in the request (to your origin server):
47                //      |       GET /proxy?url=http%3A%2F%2Fothersite.com%2Ffile HTTP/1.1
48                var plainXhr = getPlainXhr();
49                dojox.io.xhrPlugins.register(
50                        "proxy",
51                        function(method,args){
52                                // this will match on URL
53
54                                // really can be used for anything, but plain XHR will take
55                                // precedent by order of loading
56                                return true;
57                        },
58                        function(method,args,hasBody){
59                                args.url = proxyUrl + encodeURIComponent(args.url);
60                                return plainXhr.call(dojo, method, args, hasBody);
61                        });
62        };
63        var csXhrSupport;
64        dojox.io.xhrPlugins.addCrossSiteXhr = function(url, httpAdapter){
65                //      summary:
66                //              Adds W3C Cross site XHR or XDomainRequest handling for the given URL prefix
67                //
68                //      url:
69                //              Requests that start with this URL will be considered for using
70                //              cross-site XHR.
71                //
72                //      httpAdapter: This allows for adapting HTTP requests that could not otherwise be
73                //              sent with XDR, so you can use a convention for headers and PUT/DELETE methods.
74                //
75                //      description:
76                //              This can be used for servers that support W3C cross-site XHR. In order for
77                //              a server to allow a client to make cross-site XHR requests,
78                //              it should respond with the header like:
79                //      |       Access-Control: allow <*>
80                //              see: http://www.w3.org/TR/access-control/
81                var plainXhr = getPlainXhr();
82                if(csXhrSupport === undefined && window.XMLHttpRequest){
83                        // just run this once to see if we have cross-site support
84                        try{
85                                var xhr = new XMLHttpRequest();
86                                xhr.open("GET","http://testing-cross-domain-capability.com",true);
87                                csXhrSupport = true;
88                                dojo.config.noRequestedWithHeaders = true;
89                        }catch(e){
90                                csXhrSupport = false;
91                        }
92                }
93                dojox.io.xhrPlugins.register(
94                        "cs-xhr",
95                        function(method,args){
96                                return (csXhrSupport ||
97                                                (window.XDomainRequest && args.sync !== true &&
98                                                        (method == "GET" || method == "POST" || httpAdapter))) &&
99                                        (args.url.substring(0,url.length) == url);
100                        },
101                        csXhrSupport ? plainXhr : function(){
102                                var normalXhrObj = dojo._xhrObj;
103                                // we will just substitute this in temporarily so we can use XDomainRequest instead of XMLHttpRequest
104                                dojo._xhrObj = function(){
105                                       
106                                        var xdr = new XDomainRequest();
107                                        xdr.readyState = 1;
108                                        xdr.setRequestHeader = function(){}; // just absorb them, we can't set headers :/
109                                        xdr.getResponseHeader = function(header){ // this is the only header we can access
110                                                return header == "Content-Type" ? xdr.contentType : null;
111                                        }
112                                        // adapt the xdr handlers to xhr
113                                        function handler(status, readyState){
114                                                return function(){
115                                                        xdr.readyState = readyState;
116                                                        xdr.status = status;
117                                                }
118                                        }
119                                        xdr.onload = handler(200, 4);
120                                        xdr.onprogress = handler(200, 3);
121                                        xdr.onerror = handler(404, 4); // an error, who knows what the real status is
122                                        return xdr;
123                                };
124                                var dfd = (httpAdapter ? httpAdapter(getPlainXhr()) : getPlainXhr()).apply(dojo,arguments);
125                                dojo._xhrObj = normalXhrObj;
126                                return dfd;
127                        }
128                );
129        };
130        dojox.io.xhrPlugins.fullHttpAdapter = function(plainXhr,noRawBody){
131                // summary:
132                //              Provides a HTTP adaption.
133                // description:
134                //              The following convention is used:
135                //              method name -> ?http-method=PUT
136                //              Header -> http-Header-Name=header-value
137                //              X-Header -> header_name=header-value
138                //      example:
139                //              dojox.io.xhrPlugins.addXdr("http://somesite.com", dojox.io.xhrPlugins.fullHttpAdapter);
140                return function(method,args,hasBody){
141                        var content = {};
142                        var parameters = {};
143                        if(method != "GET"){
144                                parameters["http-method"] = method;
145                                if(args.putData && noRawBody){
146                                        content["http-content"] = args.putData;
147                                        delete args.putData;
148                                        hasBody = false;
149                                }
150                                if(args.postData && noRawBody){
151                                        content["http-content"] = args.postData;
152                                        delete args.postData;
153                                        hasBody = false;
154                                }
155                                method = "POST";
156                       
157                        }
158                        for(var i in args.headers){
159                                var parameterName = i.match(/^X-/) ? i.substring(2).replace(/-/g,'_').toLowerCase() : ("http-" + i);
160                                parameters[parameterName] = args.headers[i];
161                        }
162                        args.query = dojo.objectToQuery(parameters);
163                        dojo._ioAddQueryToUrl(args);
164                        args.content = dojo.mixin(args.content || {},content);
165                        return plainXhr.call(dojo,method,args,hasBody);
166                };
167        };
168
169        return dojox.io.xhrPlugins;
170});
Note: See TracBrowser for help on using the repository browser.