以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,SO,用了一天时间把这个方法给搞出来了(觉得花费的时间长了点),分享之。
代码及测试用例:
var http = require("http");var path = require("path");var fs = require("fs");function postFile(fileKeyValue, req) {var boundaryKey = Math.random().toString(16);var enddata = "
----" + boundaryKey + "--";var files = new Array();for (var i = 0; i < fileKeyValue.length; i++) { var content = "
----" + boundaryKey + "
" + "Content-Type: application/octet-stream
" + "Content-Disposition: form-data; name="" + fileKeyValue[i].urlKey + ""; filename="" + path.basename(fileKeyValue[i].urlValue) + ""
" + "Content-Transfer-Encoding: binary
"; var contentBinary = new Buffer(content, "utf-8");//当编码为ascii时,中文会乱码。 files.push({contentBinary: contentBinary, filePath: fileKeyValue[i].urlValue});}var contentLength = 0;for (var i = 0; i < files.length; i++) { var stat = fs.statSync(files[i].filePath); contentLength += files[i].contentBinary.length; contentLength += stat.size;}req.setHeader("Content-Type", "multipart/form-data; boundary=--" + boundaryKey);req.setHeader("Content-Length", contentLength + Buffer.byteLength(enddata));// 将参数发出var fileindex = 0;var doOneFile = function(){ req.write(files[fileindex].contentBinary); var fileStream = fs.createReadStream(files[fileindex].filePath, {bufferSize : 4 * 1024}); fileStream.pipe(req, {end: false}); fileStream.on("end", function() { fileindex++; if(fileindex == files.length){req.end(enddata); } else {doOneFile(); } });};if(fileindex == files.length){req.end(enddata);} else {doOneFile();}}//测试用例//http://nodejs.org/api/http.html#http_http_request_options_callbackvar files = [ {urlKey: "file1", urlValue: "E:\DFBF.jpg"}, {urlKey: "file2", urlValue: "E:\1.jpg"}, {urlKey: "file3", urlValue: "E:\Pro 空格 中文.mp3"}]var options = {host: "localhost",port: "8908" ,method: "POST",path: "/Home/Upload"}var req = http.request(options, function(res){ console.log("RES:" + res); console.log("STATUS: " + res.statusCode); console.log("HEADERS: " + JSON.stringify(res.headers)); //res.setEncoding("utf8"); res.on("data", function(chunk){console.log("BODY:" + chunk); })})req.on("error", function(e){ console.log("problem with request:" + e.message); console.log(e);})postFile(files, req);console.log("done");服务端测试,用mvc在home控制器写了个upload方法,并遍历上传的文件将其保存在硬盘上了。
只是上传大文件会有问题,估计是需要服务器进行配置,暂且不管。
服务端方法(写在了Home控制器下)
[HttpPost]public string Upload(){//HttpPostedFileBase file = this.Request.Files["file"];//file.SaveAs(file.FileName);foreach (string file in this.Request.Files){this.Request.Files[file].SaveAs(@"E:新建文件夹" + this.Request.Files[file].FileName);}return @"保存成功 路径:E:新建文件夹";}运行脚本:
node nodejsPostFile.js
运行结果: