xhrMultiPart.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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.xhrMultiPart"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.io.xhrMultiPart"] = true;
  8. dojo.provide("dojox.io.xhrMultiPart");
  9. dojo.require("dojox.uuid.generateRandomUuid");
  10. (function(){
  11. /*=====
  12. dojox.io.__xhrContentArgs = function(){
  13. // name: String
  14. // Name of the form value.
  15. // content: String
  16. // The contents of the value.
  17. // filename: String?
  18. // An optional filename to pass to the server, as defined by the boundary.
  19. // contentType: String?
  20. // An optional content-type (MIME) to pass to the server, if value is being
  21. // treated as a file.
  22. // charset: String?
  23. // Optional charset to pass, for the server to interpret the file correctly.
  24. // contentTransferEncoding: String?
  25. // Optional transfer encoding header value.
  26. this.name = name;
  27. this.content = content;
  28. this.filename = filename;
  29. this.contentType = contentType;
  30. this.charset = charset;
  31. this.contentTransferEncoding = contentTransferEncoding;
  32. }
  33. =====*/
  34. function _createPart(/* dojox.io.__xhrContentArgs */args, /* String */boundary){
  35. // summary
  36. // Assemble an array of boundary parts based on the passed values in args.
  37. if(!args["name"] && !args["content"]){
  38. throw new Error("Each part of a multi-part request requires 'name' and 'content'.");
  39. }
  40. var tmp = [];
  41. tmp.push(
  42. "--" + boundary,
  43. "Content-Disposition: form-data; name=\"" + args.name + "\"" + (args["filename"] ? "; filename=\"" + args.filename + "\"" : "")
  44. );
  45. if(args["contentType"]){
  46. var ct = "Content-Type: " + args.contentType;
  47. if(args["charset"]){
  48. ct += "; Charset=" + args.charset;
  49. }
  50. tmp.push(ct);
  51. }
  52. if(args["contentTransferEncoding"]){
  53. tmp.push("Content-Transfer-Encoding: " + args.contentTransferEncoding);
  54. }
  55. tmp.push("", args.content);
  56. return tmp; // Array
  57. }
  58. function _partsFromNode(/* DOMNode */node, /* String */boundary){
  59. // summary
  60. // Assemble an array of boundary parts based on the passed FORM node.
  61. var o=dojo.formToObject(node), parts=[];
  62. for(var p in o){
  63. if(dojo.isArray(o[p])){
  64. dojo.forEach(o[p], function(item){
  65. parts = parts.concat(_createPart({ name: p, content: item }, boundary));
  66. });
  67. } else {
  68. parts = parts.concat(_createPart({ name: p, content: o[p] }, boundary));
  69. }
  70. }
  71. return parts; // Array
  72. }
  73. /*=====
  74. dojox.io.__xhrMultiArgs = function(){
  75. // url: String
  76. // URL to server endpoint.
  77. // content: Object?
  78. // Contains properties with string values. These
  79. // properties will be serialized using multi-part
  80. // boundaries.
  81. // file: Object?
  82. // Alias for "content". Provided for backwards compatibility.
  83. // timeout: Integer?
  84. // Milliseconds to wait for the response. If this time
  85. // passes, the then error callbacks are called.
  86. // form: DOMNode?
  87. // DOM node for a form. Used to extract the form values
  88. // and send to the server; each form value will be serialized
  89. // using multi-part boundaries.
  90. // preventCache: Boolean?
  91. // Default is false. If true, then a
  92. // "dojo.preventCache" parameter is sent in the request
  93. // with a value that changes with each request
  94. // (timestamp). Useful only with GET-type requests.
  95. // handleAs: String?
  96. // Acceptable values depend on the type of IO
  97. // transport (see specific IO calls for more information).
  98. // load: Function?
  99. // function(response, ioArgs){}. response is an Object, ioArgs
  100. // is of type dojo.__IoCallbackArgs. The load function will be
  101. // called on a successful response.
  102. // error: Function?
  103. // function(response, ioArgs){}. response is an Object, ioArgs
  104. // is of type dojo.__IoCallbackArgs. The error function will
  105. // be called in an error case.
  106. // handle: Function?
  107. // function(response, ioArgs){}. response is an Object, ioArgs
  108. // is of type dojo.__IoCallbackArgs. The handle function will
  109. // be called in either the successful or error case.
  110. this.url = url;
  111. this.content = content;
  112. this.file = file;
  113. this.timeout = timeout;
  114. this.form = form;
  115. this.preventCache = preventCache;
  116. this.handleAs = handleAs;
  117. this.load = load;
  118. this.error = error;
  119. this.handle = handle;
  120. }
  121. =====*/
  122. dojox.io.xhrMultiPart = function(/* dojox.io.__xhrMultiArgs */args){
  123. if(!args["file"] && !args["content"] && !args["form"]){
  124. throw new Error("content, file or form must be provided to dojox.io.xhrMultiPart's arguments");
  125. }
  126. // unique guid as a boundary value for multipart posts
  127. var boundary=dojox.uuid.generateRandomUuid(), tmp=[], out="";
  128. if(args["file"] || args["content"]){
  129. var v = args["file"] || args["content"];
  130. dojo.forEach((dojo.isArray(v) ? v : [v]), function(item){
  131. tmp = tmp.concat(_createPart(item, boundary));
  132. });
  133. }
  134. else if(args["form"]){
  135. if(dojo.query("input[type=file]", args["form"]).length){
  136. throw new Error("dojox.io.xhrMultiPart cannot post files that are values of an INPUT TYPE=FILE. Use dojo.io.iframe.send() instead.");
  137. }
  138. tmp = _partsFromNode(args["form"], boundary);
  139. }
  140. if(tmp.length){
  141. tmp.push("--"+boundary+"--", "");
  142. out = tmp.join("\r\n");
  143. }
  144. console.log(out);
  145. return dojo.rawXhrPost(dojo.mixin(args, {
  146. contentType: "multipart/form-data; boundary=" + boundary,
  147. postData: out
  148. })); // dojo.Deferred
  149. }
  150. })();
  151. }