Sometimes there is such a demand, nodejs do webserver, upload files from the browser to the back-end server, node layer just do a data relay, if in this process, node webserver need to make appropriate data processing, and then post to the back end, Then you have to upload the file at the node layer.
First of all, upload files through the browser, the PostData format is a look like:
For example, each set of data is separated by "-----webkitformboundary ..." and ends with this delimiter, and the delimiter is completely customizable.
Each paragraph submits the data, by Content-disposition to describe, does not specify the Content-type, then the default Text/plain, if is uploads the binary file, specifies its mime-type can.
Simple encapsulation of a method to implement the node layer file upload:
/**
* Upload File
* @param files that have been processed by formidable
* @param req HttpRequest objects
* @param additional data submitted by PostData
*/
function UploadFile (Files, req, postdata) {
var boundarykey = Math.random (). toString (16);
var enddata = ' \ r \ n----' + Boundarykey + '-';
var fileslength = 0, content;
Initial data, carry the data from the post back up
Content = (function (obj) {
var rslt = [];
Object.keys (obj). ForEach (function (key) {
arr = [' \ r \ n----' + Boundarykey + ' \ r \ n '];
Arr.push (' Content-disposition:form-data; name= "' + key + '" \r\n\r\n ');
Arr.push (Obj[key]);
Rslt.push (Arr.join ('));
});
Return Rslt.join (");
}) (PostData);
Assemble data
Object.keys (Files). ForEach (function (key) {
if (!files.hasownproperty (key)) {
Delete Files.key;
Return
}
Content = = ' \ r \ n----' + Boundarykey + ' \ r \ n ' +
' content-type:application/octet-stream\r\n ' +
' Content-disposition:form-data; Name= "' + key + '";
' Filename= ' + files[key].name + ' "; \ r \ n ' +
' content-transfer-encoding:binary\r\n\r\n ';
Files[key].contentbinary = new Buffer (content, ' utf-8 ');
Fileslength + + files[key].contentbinary.length + fs.statsync (files[key].path). Size;
});
Req.setheader (' Content-type ', ' multipart/form-data; boundary=--' + Boundarykey);
Req.setheader (' content-length ', Fileslength + buffer.bytelength (enddata));
Perform an upload
var allfiles = Object.keys (files);
var filenum = allfiles.length;
var uploadedcount = 0;
Allfiles.foreach (function (key) {
Req.write (files[key].contentbinary);
var fileStream = Fs.createreadstream (Files[key].path, {buffersize:4 * 1024});
Filestream.on (' End ', function () {
After uploading a successful file, delete the temporary file.
Fs.unlink (Files[key].path);
uploadedcount++;
if (Uploadedcount = = FileNum) {
If it's the last file, it ends normally.
Req.end (Enddata);
}
});
Filestream.pipe (req, {end:false});
});
}
The idea is, the code is not complicated, and it may be extra attention that In http.request response processing, response.headers may be gzip, this time the buffer can not be directly ToString, need to pass zlib decoding and then converted to string, presumably thinking:
var result = [];
Response.on (' Data ', function (chunk) {
Result.push (chunk);
});
Handling response
var _dealresponse = function (data) {
var buffer = data;
try {
data = data.tostring (' UTF8 ');
data = data? (Json.parse (data) | | data): false;
} catch (Err) {
Interface returned data format exception, parsing failed
Console.log (ERR);
}
Self.res.writeHead (Response.statuscode, ' OK ', {
' Content-type ': ' Text/plain; Charset=utf-8 ',
' Content-length ': buffer.length
});
Self.res.write (buffer);
Self.res.end ();
};
Response.on (' end '), function () {
result = Buffer.concat (result);
// Gzip data that requires zlib decoding
if (response.headers[' content-encoding '] = = ' gzip ') {
& nbsp; zlib.gunzip (result, function (err, dezipped) {
var data = err? New Buffer (' {} '): dezipped;
_dealresponse (data);
});
} else {
_dealresponse (result);
}
});
Mark, maybe you just need to pass by.