您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

Node层模拟实现multipart表单文件上传详解

2024/3/28 9:01:39发布15次查看
有时候就是有这样的需求,nodejs做webserver,从浏览器端上传文件到后端服务器,node层只是做一个数据中转,如果在这个过程中,node webserver需要对数据进行适当加工,然后再post到后端,那么就得在node层模拟文件上传了。本文主要为大家分享一篇node层模拟实现multipart表单的文件上传示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧,希望能帮助到大家。
首先,通过浏览器上传文件,postdata格式是长着个样子的:
屏幕快照 2014-11-22 下午9.18.45.png
如图,每一组数据其实就是用“-----webkitformboundary.....”分隔开的,最后再用这个分隔符结束,而且,这个分隔符完全是可自定义的。
每一段提交数据,则通过content-disposition来描述,未指定content-type,则默认text/plain,如果是上传的二进制文件,指定其mime-type即可。
简单封装一个方法,实现node层的文件上传:
/**  * 上传文件  * @param files  经过formidable处理过的文件  * @param req  httprequest对象  * @param postdata 额外提交的数据  */ function uploadfile(files, req, postdata) {  var boundarykey = math.random().tostring(16);  var enddata = '\r\n----' + boundarykey + '--';  var fileslength = 0, content;  // 初始数据,把post过来的数据都携带上去  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);  // 组装数据  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));  // 执行上传  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 () {    // 上传成功一个文件之后,把临时文件删了    fs.unlink(files[key].path);    uploadedcount++;    if (uploadedcount == filenum) {     // 如果已经是最后一个文件,那就正常结束     req.end(enddata);    }   });   filestream.pipe(req, {end: false});  }); }
思路就这样,代码也不复杂,可能额外需要注意的是,在http.request的response处理中,response.headers可能是gzip的,这个时候buffer不能直接tostring,需要通过zlib解码再转换为string,大概思路:
var result = []; response.on('data', function (chunk) {  result.push(chunk); }); // 处理response var _dealresponse = function (data) {  var buffer = data;  try {   data = data.tostring('utf8');   data = data ? (json.parse(data) || data) : false;  } catch (err) {   // 接口返回数据格式异常,解析失败   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 的数据,需要zlib解码  if (response.headers['content-encoding'] == 'gzip') {   zlib.gunzip(result, function (err, dezipped) {    var data = err ? new buffer('{}') : dezipped;    _dealresponse(data);   });  } else {   _dealresponse(result);  } });
mark一下,也许你路过正好需要~~~
相关推荐:
form表单上传图片表单标签中enctype=multipart/form-data的作用
php http请求类,支持get,post,multipart/form-data
为什么上传文件的表单需要设置enctype=multipart/form-data
以上就是node层模拟实现multipart表单文件上传详解的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product