如何处理nodejs中的http请求中的表单数据 [英] How to handle form data in an http requests in nodejs

查看:197
本文介绍了如何处理nodejs中的http请求中的表单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个代码让客户端上传两个文件在服务器上。因为我使用了director路由器,所以我设置了一个这样的监听器:

  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

第一个文件的内容

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


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

第二个文件的内容

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

我已经通过几个正则表达式处理了这个问题,用于提取请求中的每个文件名和每个文件内容.chunks 变量,但浏览器有不同的倾向(对于这些边界,例如谷歌浏览器是这样的:'------ WebKit ...'),我想知道是否有一个直接的方式来解析文件名和文件内容(显然来自 request.chunks 不是请求)与一些模块像强大的或多部分或查询字符串?




感谢@micnic,我想出了一个头解析器。这可能需要在这个级别的修订:
$ b $ pre $ exports.parseMultipart = function(request){

//将块转换为字符串
var str = request.chunks.toString();

//获取边界pf头
var boundry =' - '+ request.headers [content-type]。substring(request.headers [content-type ] .indexOf('=')+ 1,request.headers [content-type]。

//初始化
var request_data = {};
index = 0;


//对于每个表单元素,将值存储在request_data
中(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 [
j = str.indexOf(\\\
\r\\\
+ boundry,i);
fileContent = str。 substring(i,j);
value [content] = fileContent;
} else {
value [type] =field;
i = j + 5 ;
j = str.indexOf(\r\\\
+ boundry,i);
value [content] = str.substring(i,j);
}
index = str.indexOf(boundry,index)+ 2;
request_data [name] = value;
}
return request_data;
}


解决方案

对于我的模块 https://github.com/micnic/simpleS/blob/ccc8e600013da70d5204c1b66149e834d2c0fea2/utils/utils.js#L365



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

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



从那里:

 <$ c (); 
$ b $ * b

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:\\\
\\\
');
res.end(util.inspect({fields:fields,files:files}));
});

/ * ... * /


I am writing a code to let the client upload two files on the server. Since I used the director router, I have set a listener like this:

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

and here is the console.log of the chunks when a client uploads a file (based on the browser the boundaries change):

-----------------------------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--

I have handled the problem by a few regular expressions for extracting each file-name and each file-content on the request.chunks variable, but the browsers have different tendencies (for these boundries, for example for google chrome is like this: '------WebKit...') and I wonder if there is a direct way to parse file-name and file-content (obviously from request.chunks not request) with some modules like formidable or multi-part or querystring?


Thanks to @micnic, I came up with a parser for the headers. It may need revisions which are welcome at this level:

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;
}

解决方案

For my module simpleS I wrote a parser: https://github.com/micnic/simpleS/blob/ccc8e600013da70d5204c1b66149e834d2c0fea2/utils/utils.js#L365

May be it's a bit difficult to understand it, but it does the work.

"... I wonder if there is a direct way to parse file-name and file-content with some modules like formidable or multi-part or querystring? ...", did you read formidable's docs?

from there:

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}));
});

/* ... */

这篇关于如何处理nodejs中的http请求中的表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆