nodejs 实现模拟form表单上传文件


Posted in NodeJs onJuly 14, 2014

以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,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 = '\r\n----' + boundaryKey + '--';

  var files = new Array();
  for (var i = 0; i < fileKeyValue.length; i++) {
   var content = "\r\n----" + boundaryKey + "\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Disposition: form-data; name=\"" + fileKeyValue[i].urlKey + "\"; filename=\"" + path.basename(fileKeyValue[i].urlValue) + "\"\r\n" + "Content-Transfer-Encoding: binary\r\n\r\n";
   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_callback
var 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

运行结果:

nodejs 实现模拟form表单上传文件

NodeJs 相关文章推荐
基于NodeJS的前后端分离的思考与实践(二)模版探索
Sep 26 NodeJs
nodejs下打包模块archiver详解
Dec 03 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
Aug 16 NodeJs
Nodejs进阶:express+session实现简易登录身份认证
Apr 24 NodeJs
NodeJS 实现手机短信验证模块阿里大于功能
Jun 19 NodeJs
深入学习nodejs中的async模块的使用方法
Jul 12 NodeJs
nodejs基于express实现文件上传的方法
Mar 19 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
通过Nodejs搭建网站简单实现注册登录流程
Jun 14 NodeJs
nodejs使用socket5进行代理请求的实现
Feb 21 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 NodeJs
在NodeJs中使用node-schedule增加定时器任务的方法
Jun 08 NodeJs
14款NodeJS Web框架推荐
Jul 11 #NodeJs
基于promise.js实现nodejs的promises库
Jul 06 #NodeJs
我的NodeJs学习小结(一)
Jul 06 #NodeJs
nodejs中使用monk访问mongodb
Jul 06 #NodeJs
nodejs之请求路由概述
Jul 05 #NodeJs
Nodejs中自定义事件实例
Jun 20 #NodeJs
Nodejs sublime text 3安装与配置
Jun 19 #NodeJs
You might like
php5.3提示Function ereg() is deprecated Error问题解决方法
2014/11/12 PHP
PHP中使用Memache作为进程锁的操作类分享
2015/03/30 PHP
jQuery 跨域访问问题解决方法
2009/12/02 Javascript
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
js onload事件不起作用示例分析
2013/10/09 Javascript
JS实现一键回顶功能示例代码
2013/10/28 Javascript
BootStrap下拉菜单和滚动监听插件实现代码
2016/09/26 Javascript
对于Javascript 执行上下文的全面了解
2017/09/05 Javascript
改变vue请求过来的数据中的某一项值的方法(详解)
2018/03/08 Javascript
浅谈手写node可读流之流动模式
2018/06/01 Javascript
小程序云开发部署攻略(图文教程)
2018/10/30 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
echarts 使用formatter 修改鼠标悬浮事件信息操作
2020/07/20 Javascript
[47:42]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[05:37]DOTA2-DPC中国联赛 正赛 Elephant vs iG 选手采访
2021/03/11 DOTA
Python md5与sha1加密算法用法分析
2017/07/14 Python
python利用小波分析进行特征提取的实例
2019/01/09 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
python利用百度云接口实现车牌识别的示例
2020/02/21 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
详解pycharm2020.1.1专业版安装指南(推荐)
2020/08/07 Python
python利用tkinter实现图片格式转换的示例
2020/09/28 Python
解决python3中os.popen()出错的问题
2020/11/19 Python
基于Python-turtle库绘制路飞的草帽骷髅旗、美国队长的盾牌、高达的源码
2021/02/18 Python
python 制作本地应用搜索工具
2021/02/27 Python
Styleonme中文网:韩国高档人气品牌
2017/06/21 全球购物
芝加哥牛排公司:Chicago Steak Company
2018/10/31 全球购物
英国天然抗衰老护肤品品牌:Nakin Skin Care
2019/04/16 全球购物
管理站站长岗位职责
2013/11/27 职场文书
八年级数学教学反思
2014/01/31 职场文书
党员公开承诺书
2014/03/25 职场文书
医务人员医德考评自我评价
2015/03/03 职场文书
加薪申请书应该这样写!
2019/07/04 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js
Vue.js中v-bind指令的用法介绍
2022/03/13 Vue.js
MySQL数据库Innodb 引擎实现mvcc锁
2022/05/06 MySQL