xhrMultiPart.js 5.2 KB

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