使用nodejs来模拟form表单进行文件上传,可以同时上传多个文件。

以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,SO,用了一天时间把这个方法给搞出来了(觉得花费的时间长了点),分享之。

代码及测试用例:

var http = require('http');
var path = require('path');
var fs = require('fs'); function postFile(fileDataInfo, fileKeyValue, req) {
var boundaryKey = Math.random().toString(16);
var enddata = '\r\n----' + boundaryKey + '--'; var dataLength = 0;
var dataArr = new Array();
for (var i = 0; i < fileDataInfo.length; i++) {
var dataInfo = "\r\n----" + boundaryKey + "\r\n" + "Content-Disposition: form-data; name=\"" + fileDataInfo[i].urlKey + "\"\r\n\r\n" + fileDataInfo[i].urlValue;
var dataBinary = new Buffer(dataInfo, "utf-8");
dataLength += dataBinary.length;
dataArr.push({
dataInfo: dataInfo
});
} 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 filePath = files[i].filePath;
if (fs.existsSync(filePath)) {
var stat = fs.statSync(filePath);
contentLength += stat.size;
} else {
contentLength += new Buffer("\r\n", 'utf-8').length;
}
contentLength += files[i].contentBinary.length;
} req.setHeader('Content-Type', 'multipart/form-data; boundary=--' + boundaryKey);
req.setHeader('Content-Length', dataLength + contentLength + Buffer.byteLength(enddata)); // 将参数发出
for (var i = 0; i < dataArr.length; i++) {
req.write(dataArr[i].dataInfo)
//req.write('\r\n')
} var fileindex = 0;
var doOneFile = function() {
req.write(files[fileindex].contentBinary);
var currentFilePath = files[fileindex].filePath;
if (fs.existsSync(currentFilePath)) {
var fileStream = fs.createReadStream(currentFilePath, {bufferSize: 4 * 1024});
fileStream.pipe(req, {end: false});
fileStream.on('end', function() {
fileindex++;
if (fileindex == files.length) {
req.end(enddata);
} else {
doOneFile();
}
});
} else {
req.write("\r\n");
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 fileDataInfo = [
{urlKey: "abc", urlValue: "空格 中文"},
{urlKey: "def", urlValue: "asdfasfs123477"}
] var files = [
{urlKey: "file1", urlValue: "E:\\1.jpg"},
{urlKey: "file2", urlValue: "文件不存在"},
{urlKey: "file3", urlValue: ""},
{urlKey: "file4", urlValue: ""},
{urlKey: "file5", urlValue: "E:\\Pro 中文 空格.mp3"},
{urlKey: "file6", urlValue: "E:\\DFBF.jpg"},
{urlKey: "file7", urlValue: ""}
] 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(fileDataInfo, files, req);
console.log("done");

服务端测试,用mvc在home控制器写了个upload方法,并遍历上传的文件将其保存在硬盘上了。

只是上传大文件会有问题,估计是需要服务器进行配置,暂且不管。

服务端方法(写在了Home控制器下)

        [HttpPost]
public string Upload()
{
foreach (string file in this.Request.Files)
{
string strFileName = this.Request.Files[file].FileName;
if (string.IsNullOrEmpty(strFileName))
continue;
this.Request.Files[file].SaveAs(@"E:\新建文件夹\" + strFileName);
}
StringBuilder sb = new StringBuilder();
foreach (string item in this.Request.Form.AllKeys)
{
sb.AppendLine(string.Format("key:{0} value:{1}", item, this.Request.Form[item]));
}
sb.AppendLine(@"保存成功 路径:E:\新建文件夹\");
return sb.ToString();
}

运行脚本:

node nodejsPostFile.js

运行结果:

示例下载

nodejsPostFile4.rar

nodejs 模拟form表单上传文件的更多相关文章

  1. django 基于form表单上传文件和基于ajax上传文件

    一.基于form表单上传文件 1.html里是有一个input type="file" 和 ‘submit’的标签 2.vies.py def fileupload(request ...

  2. 巨蟒python全栈开发django11:ajax&&form表单上传文件contentType

    回顾: 什么是异步? 可以开出一个线程,我发出请求,不用等待返回,可以做其他事情. 什么是同步? 同步就是,我发送出了一个请求,需要等待返回给我信息,我才可以操作其他事情. 局部刷新是什么? 通过jq ...

  3. vue form表单上传文件

    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js">< ...

  4. 使用form表单上传文件

    在使用form表单上传文件时候,input[type='file']是必然会用的,其中有一些小坑需要避免. 1.form的 enctype="multipart/form-data" ...

  5. JsonResponse类的使用、form表单上传文件补充、CBV和FBV、HTML的模板语法之传值与过滤器

    昨日内容回顾 Django请求生命周期 # 1.浏览器发起请求 到达Django的socket服务端(web服务网关接口) 01 wsgiref 02 uwsgi + nginx 03 WSGI协议 ...

  6. PHP CURL 模拟form表单上传遇到的小坑

    1:引用的时候 $parans ['img']=new \CURLFile($param); 传入的文件 在PHP版本5.5以上记得new CURLFile 不然会上传不成功 /** * http p ...

  7. PHP 后台程序配置config文件,及form表单上传文件

    一,配置config文件 1获取config.php文件数组, 2获取form 表单提交的值 3保存更新config.php文件,代码如下: $color=$_POST['color']; $back ...

  8. form表单上传文件使用multipart请求处理

    在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——spring MVC其中的一个优势.Spring通过对Serv ...

  9. 通过form表单上传文件获取后台传来的数据

    小伙伴是不是遇到过这样的问题,通过submit提交form表单的时候,不知怎么获取后台传来的返回值.有的小伙伴就会说你不会发送ajax,其实也会.假如提交的form表单中含有文件,怎么办? 步骤1:想 ...

随机推荐

  1. WEB-INF文件夹的位置和作用

    WEB-INF简介 TomCat 服务器下的WEB-INF文件夹是一个非常安全的文件,在页面中不能直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问. WEB-INF文件 ...

  2. windows下cocos2dx3.0开发环境及Android编译环境搭建

    cocos2dx更新到了3.x版本号,自己一直没有换,如今开发组要求统一换版本号,我就把搭建好开发环境的过程记录下来. 一.Windowns下开发环境搭建 1.  所需工具         1)coc ...

  3. Codeforces Round #256 (Div. 2) C. Painting Fence 或搜索DP

    C. Painting Fence time limit per test 1 second memory limit per test 512 megabytes input standard in ...

  4. 利用jsoup爬取百度网盘资源分享连接(多线程)

    突然有一天就想说能不能用某种方法把百度网盘上分享的资源连接抓取下来,于是就动手了.知乎上有人说过最好的方法就是http://pan.baidu.com/wap抓取,一看果然链接后面的uk值是一串数字, ...

  5. Windows Phone开发(8):关于导航的小技巧

    原文:Windows Phone开发(8):关于导航的小技巧 前文用几个例子对导航做了简单介绍,在一般应用中,使用上一篇文章中说到的方法,其实也够用了,不过,为了能够处理一些特殊的情况,有几个小技巧还 ...

  6. mysql计算指定的时间TPS

    <pre name="code" class="sql">有朋友留言,需要监视如早晨在规定时间内9设置18分TPS,写一个10在几秒钟内TPS方法. ...

  7. Hadoop-2.2.0中文文档—— MapReduce下一代- 可插入的 Shuffle 和 Sort

    简单介绍 可插入的 shuffle 和 sort 功能,同意在shuffle 和 sort 逻辑中用可选择的实现类替换.这个情况的样例是:用一个不是HTTP的应用协议,如RDMA来 shuffle 从 ...

  8. zTree市县实现三个梯级数据库映射

    zTree市县实现三个梯级数据库映射 Province.hbm.xml: <?xml version="1.0" encoding="UTF-8"? &g ...

  9. LA3026 - Period(KMP)

    For each prefix of a given string S with N characters (each character has an ASCII code between 97 a ...

  10. java提高篇(十)-----强制类型转换

    在java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换. 在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需 ...