1 | define([ |
---|
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 | /*===== |
---|
11 | var __xhrContentArgs = { |
---|
12 | // name: String |
---|
13 | // Name of the form value. |
---|
14 | // content: String |
---|
15 | // The contents of the value. |
---|
16 | // filename: String? |
---|
17 | // An optional filename to pass to the server, as defined by the boundary. |
---|
18 | // contentType: String? |
---|
19 | // An optional content-type (MIME) to pass to the server, if value is being |
---|
20 | // treated as a file. |
---|
21 | // charset: String? |
---|
22 | // Optional charset to pass, for the server to interpret the file correctly. |
---|
23 | // contentTransferEncoding: String? |
---|
24 | // Optional transfer encoding header value. |
---|
25 | }; |
---|
26 | =====*/ |
---|
27 | function _createPart(/*__xhrContentArgs */args, /* String */boundary){ |
---|
28 | // summary: |
---|
29 | // Assemble an array of boundary parts based on the passed values in args. |
---|
30 | if(!args["name"] && !args["content"]){ |
---|
31 | throw new Error("Each part of a multi-part request requires 'name' and 'content'."); |
---|
32 | } |
---|
33 | |
---|
34 | var tmp = []; |
---|
35 | tmp.push( |
---|
36 | "--" + boundary, |
---|
37 | "Content-Disposition: form-data; name=\"" + args.name + "\"" + (args["filename"] ? "; filename=\"" + args.filename + "\"" : "") |
---|
38 | ); |
---|
39 | |
---|
40 | if(args["contentType"]){ |
---|
41 | var ct = "Content-Type: " + args.contentType; |
---|
42 | if(args["charset"]){ |
---|
43 | ct += "; Charset=" + args.charset; |
---|
44 | } |
---|
45 | tmp.push(ct); |
---|
46 | } |
---|
47 | |
---|
48 | if(args["contentTransferEncoding"]){ |
---|
49 | tmp.push("Content-Transfer-Encoding: " + args.contentTransferEncoding); |
---|
50 | } |
---|
51 | tmp.push("", args.content); |
---|
52 | return tmp; // Array |
---|
53 | } |
---|
54 | |
---|
55 | function _partsFromNode(/* DOMNode */node, /* String */boundary){ |
---|
56 | // summary: |
---|
57 | // Assemble an array of boundary parts based on the passed FORM node. |
---|
58 | var o=dojo.formToObject(node), parts=[]; |
---|
59 | for(var p in o){ |
---|
60 | if(dojo.isArray(o[p])){ |
---|
61 | dojo.forEach(o[p], function(item){ |
---|
62 | parts = parts.concat(_createPart({ name: p, content: item }, boundary)); |
---|
63 | }); |
---|
64 | } else { |
---|
65 | parts = parts.concat(_createPart({ name: p, content: o[p] }, boundary)); |
---|
66 | } |
---|
67 | } |
---|
68 | return parts; // Array |
---|
69 | } |
---|
70 | |
---|
71 | /*===== |
---|
72 | var __xhrMultiArgs = { |
---|
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 | }; |
---|
109 | =====*/ |
---|
110 | dojox.io.xhrMultiPart = function(/* __xhrMultiArgs */args){ |
---|
111 | if(!args["file"] && !args["content"] && !args["form"]){ |
---|
112 | throw new Error("content, file or form must be provided to dojox.io.xhrMultiPart's arguments"); |
---|
113 | } |
---|
114 | |
---|
115 | // unique guid as a boundary value for multipart posts |
---|
116 | var boundary=generateRandomUuid(), tmp=[], out=""; |
---|
117 | if(args["file"] || args["content"]){ |
---|
118 | var v = args["file"] || args["content"]; |
---|
119 | dojo.forEach((dojo.isArray(v) ? v : [v]), function(item){ |
---|
120 | tmp = tmp.concat(_createPart(item, boundary)); |
---|
121 | }); |
---|
122 | } |
---|
123 | else if(args["form"]){ |
---|
124 | if(query("input[type=file]", args["form"]).length){ |
---|
125 | throw new Error("dojox.io.xhrMultiPart cannot post files that are values of an INPUT TYPE=FILE. Use dojo.io.iframe.send() instead."); |
---|
126 | } |
---|
127 | tmp = _partsFromNode(args["form"], boundary); |
---|
128 | } |
---|
129 | |
---|
130 | if(tmp.length){ |
---|
131 | tmp.push("--"+boundary+"--", ""); |
---|
132 | out = tmp.join("\r\n"); |
---|
133 | } |
---|
134 | |
---|
135 | console.log(out); |
---|
136 | |
---|
137 | return dojo.rawXhrPost(dojo.mixin(args, { |
---|
138 | contentType: "multipart/form-data; boundary=" + boundary, |
---|
139 | postData: out |
---|
140 | })); // dojo.Deferred |
---|
141 | }; |
---|
142 | |
---|
143 | return dojox.io.xhrMultiPart; |
---|
144 | }); |
---|