2013-05-22 53 views
1

我正在编写一个代码让客户端上传服务器上的两个文件。 (基于边界改变浏览器)如何在nodejs中处理http请求中的表单数据

request.chunks = []; 
request.on('data', function (chunk) { 
    request.chunks.push(chunk.toString()); 
}; 

,这里是当客户端上传文件的数据块的的console.log:由于我使用的路由器的导演,我已经设置了听众这样

-----------------------------7dd2c419180232 
Content-Disposition: form-data; name="filename" 


-----------------------------7dd2c419180232 
Content-Disposition: form-data; name="uploadfile"; filename="first.txt" 
Content-Type: application/octet-stream 

the content of first file 

-----------------------------7dd2c419180232 
Content-Disposition: form-data; name="wfilename" 


-----------------------------7dd2c419180232 
Content-Disposition: form-data; name="wuploadfile"; filename="second.txt" 
Content-Type: application/octet-stream 

the content of the second file 

-----------------------------7dd2c419180232-- 

我已经几个正则表达式处理的问题用于提取每个文件名,并在request.chunks变量中的每个文件的内容,但浏览器有不同的倾向(这些boundries,例如谷歌浏览器是这个样子:'------ WebKit ...'),我想知道是否有直接的方法来解析文件名和文件内容(显然是从request.chunks不是request)与一些模块如强大或多部分或querystring?


感谢@micnic,我想出了一个头文件解析器。这可能需要在此级别欢迎修订:

exports.parseMultipart = function(request) { 

    // Convert the chunks to string 
    var str = request.chunks.toString(); 

    // Get the boundry out pf header 
    var boundry = '--' + request.headers["content-type"].substring(request.headers["content-type"].indexOf('=')+1, request.headers["content-type"].length); 

    // Initialization 
    var request_data = {}; 
    index = 0; 


    // For each form element, store the value in request_data 
    while (str.indexOf(boundry, index) != -1) { 
     index += boundry.length; 
     i = str.indexOf(" name=\"",index); 
     j = str.indexOf("\"",i+7); 
     name = str.substring(i+7,j); 
     var value = {}; 
     if (str.charAt(j+1)==';') { 
      value["type"] = "file"; 
      i = j + 3; 
      j = str.indexOf("\"",i+14); 
      filename = str.substring(i+10, j); 
      value["filename"] = filename; 
      i = j + 17; 
      j = str.indexOf("\r", i); 
      contentType = str.substring(i, j); 
      value["content-type"] = contentType; 
      i = j + 4; 
      j = str.indexOf("\n\r\n" + boundry, i); 
      fileContent = str.substring(i, j); 
      value["content"] = fileContent; 
     } else { 
      value["type"] = "field"; 
      i = j + 5; 
      j = str.indexOf("\r\n" + boundry,i); 
      value["content"] = str.substring(i,j); 
     } 
     index = str.indexOf(boundry, index) + 2; 
     request_data[name] = value; 
    } 
    return request_data; 
} 
+0

你提到的强大,然后用它;-) – TheHippo

+0

@TheHippo强大的用途要求的身体,但我想用块变量! – orezvani

回答

0

对于我的模块simpleS我写了一个解析器: https://github.com/micnic/simpleS/blob/ccc8e600013da70d5204c1b66149e834d2c0fea2/utils/utils.js#L365

可能这是一个有点难以理解,但它做的工作。

“......我不知道是否有直接的方式来解析文件名和文件内容与一些模块,如强大或多部分或查询字符串?”,你读过强大的文档?

从那里:

var formidable = require('formidable'); 

/* ... */ 

var form = new formidable.IncomingForm(); 

form.parse(req, function(err, fields, files) { 
    res.writeHead(200, {'content-type': 'text/plain'}); 
    res.write('received upload:\n\n'); 
    res.end(util.inspect({fields: fields, files: files})); 
}); 

/* ... */ 
+0

感谢您的第一个解决方案,但第二个与我的数据侦听器之后为空的'req'一起工作!我想要一个获取'req.chunks'并解析字段和文件的模块。 – orezvani

+0

非常感谢您的代码,我编写了另一个代码来将一个大表单解析为一个JSON对象,并且如果您在SimpleS中发现它很有用,我可以与您分享它 – orezvani

+0

我希望看到它,并且可以帮助我改进它 – micnic