Node层模拟实现multipart表单的文件上传示例

 更新时间:2018年01月02日 09:58:02   作者:itKingOne  
下面小编就为大家分享一篇Node层模拟实现multipart表单的文件上传示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

有时候就是有这样的需求,Nodejs做webserver,从浏览器端上传文件到后端服务器,Node层只是做一个数据中转,如果在这个过程中,Node webserver需要对数据进行适当加工,然后再Post到后端,那么就得在Node层模拟文件上传了。

首先,通过浏览器上传文件,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一下,也许你路过正好需要~~~

以上这篇Node层模拟实现multipart表单的文件上传示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • node.js调用Chrome浏览器打开链接地址的方法

    node.js调用Chrome浏览器打开链接地址的方法

    其实在Node.JS中打开浏览器网址非常简单,但还是有必要整理下分享给有需要的朋友们,这篇文章主要给大家介绍了node.js如何调用Chrome浏览器打开链接地址的方法,文中介绍的非常详细,需要的朋友们下面随着小编来一起看看吧。
    2017-05-05
  • Node.js中用D3.js的方法示例

    Node.js中用D3.js的方法示例

    这篇文章主要给大家介绍了在Node.js中用D3.js的方法,文中分别介绍了如何安装模块和一小段简单的示例代码,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-01-01
  • node.js与C语言 实现遍历文件夹下最大的文件,并输出路径,大小

    node.js与C语言 实现遍历文件夹下最大的文件,并输出路径,大小

    这篇文章主要介绍了node.js与C语言 实现遍历文件夹下最大的文件,并输出路径,大小的相关资料,需要的朋友可以参考下
    2017-01-01
  • NodeJS测试框架mocha入门教程

    NodeJS测试框架mocha入门教程

    本文给大家简单介绍了NodeJS里最常用的测试框架--mocha的安装以及简单的使用方法,支持直接在browser上跑Javascript代码测试,这里推荐给大家
    2017-03-03
  • node.js读写json文件的方法

    node.js读写json文件的方法

    这篇文章介绍了node.js读写json文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • express框架实现基于Websocket建立的简易聊天室

    express框架实现基于Websocket建立的简易聊天室

    本篇文章主要介绍了express框架实现基于Websocket建立的简易聊天室,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • Node实现前端本地开发接口代理服务

    Node实现前端本地开发接口代理服务

    本文主要介绍了Node实现前端本地开发接口代理服务,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • 使用nvm实现多个nodejs版本的快速切换

    使用nvm实现多个nodejs版本的快速切换

    NodeJS的升级比较快,在开发中要使用最新的版本,必须经常升级,但对于一些老项目可能又要使用低版本的NodeJS,使用nvm工具可以方便的管理下载的NodeJS版本,并通过命令实现NodeJS版本的快速切换,需要的朋友可以参考下
    2024-09-09
  • node.js Promise对象的使用方法实例分析

    node.js Promise对象的使用方法实例分析

    这篇文章主要介绍了node.js Promise对象的使用方法,结合实例形式分析了node.js中Promise对象的功能、定义、调用方法及相关使用技巧,需要的朋友可以参考下
    2019-12-12
  • node.js安装及环境配置超详细步骤讲解(Windows系统安装包方式)

    node.js安装及环境配置超详细步骤讲解(Windows系统安装包方式)

    这篇文章主要介绍了node.js安装及环境配置超详细教程(Windows系统安装包方式),本文分步骤通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2023-02-02

最新评论