154 lines
5 KiB
JavaScript
154 lines
5 KiB
JavaScript
|
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
|
||
|
}
|
||
|
})();
|