xhrPlugins.js 5.8 KB

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