dojo.provide("dojox.io.xhrMultiPart"); dojo.require("dojox.uuid.generateRandomUuid"); (function(){ /*===== dojox.io.__xhrContentArgs = function(){ // name: String // Name of the form value. // content: String // The contents of the value. // filename: String? // An optional filename to pass to the server, as defined by the boundary. // contentType: String? // An optional content-type (MIME) to pass to the server, if value is being // treated as a file. // charset: String? // Optional charset to pass, for the server to interpret the file correctly. // contentTransferEncoding: String? // Optional transfer encoding header value. this.name = name; this.content = content; this.filename = filename; this.contentType = contentType; this.charset = charset; this.contentTransferEncoding = contentTransferEncoding; } =====*/ function _createPart(/* dojox.io.__xhrContentArgs */args, /* String */boundary){ // summary // Assemble an array of boundary parts based on the passed values in args. if(!args["name"] && !args["content"]){ throw new Error("Each part of a multi-part request requires 'name' and 'content'."); } var tmp = []; tmp.push( "--" + boundary, "Content-Disposition: form-data; name=\"" + args.name + "\"" + (args["filename"] ? "; filename=\"" + args.filename + "\"" : "") ); if(args["contentType"]){ var ct = "Content-Type: " + args.contentType; if(args["charset"]){ ct += "; Charset=" + args.charset; } tmp.push(ct); } if(args["contentTransferEncoding"]){ tmp.push("Content-Transfer-Encoding: " + args.contentTransferEncoding); } tmp.push("", args.content); return tmp; // Array } function _partsFromNode(/* DOMNode */node, /* String */boundary){ // summary // Assemble an array of boundary parts based on the passed FORM node. var o=dojo.formToObject(node), parts=[]; for(var p in o){ if(dojo.isArray(o[p])){ dojo.forEach(o[p], function(item){ parts = parts.concat(_createPart({ name: p, content: item }, boundary)); }); } else { parts = parts.concat(_createPart({ name: p, content: o[p] }, boundary)); } } return parts; // Array } /*===== dojox.io.__xhrMultiArgs = function(){ // url: String // URL to server endpoint. // content: Object? // Contains properties with string values. These // properties will be serialized using multi-part // boundaries. // file: Object? // Alias for "content". Provided for backwards compatibility. // timeout: Integer? // Milliseconds to wait for the response. If this time // passes, the then error callbacks are called. // form: DOMNode? // DOM node for a form. Used to extract the form values // and send to the server; each form value will be serialized // using multi-part boundaries. // preventCache: Boolean? // Default is false. If true, then a // "dojo.preventCache" parameter is sent in the request // with a value that changes with each request // (timestamp). Useful only with GET-type requests. // handleAs: String? // Acceptable values depend on the type of IO // transport (see specific IO calls for more information). // load: Function? // function(response, ioArgs){}. response is an Object, ioArgs // is of type dojo.__IoCallbackArgs. The load function will be // called on a successful response. // error: Function? // function(response, ioArgs){}. response is an Object, ioArgs // is of type dojo.__IoCallbackArgs. The error function will // be called in an error case. // handle: Function? // function(response, ioArgs){}. response is an Object, ioArgs // is of type dojo.__IoCallbackArgs. The handle function will // be called in either the successful or error case. this.url = url; this.content = content; this.file = file; this.timeout = timeout; this.form = form; this.preventCache = preventCache; this.handleAs = handleAs; this.load = load; this.error = error; this.handle = handle; } =====*/ dojox.io.xhrMultiPart = function(/* dojox.io.__xhrMultiArgs */args){ if(!args["file"] && !args["content"] && !args["form"]){ throw new Error("content, file or form must be provided to dojox.io.xhrMultiPart's arguments"); } // unique guid as a boundary value for multipart posts var boundary=dojox.uuid.generateRandomUuid(), tmp=[], out=""; if(args["file"] || args["content"]){ var v = args["file"] || args["content"]; dojo.forEach((dojo.isArray(v) ? v : [v]), function(item){ tmp = tmp.concat(_createPart(item, boundary)); }); } else if(args["form"]){ if(dojo.query("input[type=file]", args["form"]).length){ throw new Error("dojox.io.xhrMultiPart cannot post files that are values of an INPUT TYPE=FILE. Use dojo.io.iframe.send() instead."); } tmp = _partsFromNode(args["form"], boundary); } if(tmp.length){ tmp.push("--"+boundary+"--", ""); out = tmp.join("\r\n"); } console.log(out); return dojo.rawXhrPost(dojo.mixin(args, { contentType: "multipart/form-data; boundary=" + boundary, postData: out })); // dojo.Deferred } })();