xhrPlugins.js 6.1 KB

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