使用request.on()和querystring.parse()的POST方法的js / nodejs基本初学者服务器

时间:2016-04-05 02:51:17

标签: javascript node.js post

我开始在javascript之后在我的网络课程中学习一些nodejs来制作一些简单的服务器,并在下面举例说明:

var http = require('http');
var url = require('url');
var querystring = require('querystring');


function onRequest(request, response) {

    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;  // data sent via http protocol will always be sent as a string and can be concatenated
            // if body > 1e6 === 1* Math.pow(10,6) ~~~ 1MB
            // flood attack or faulty client
            // (code 413: request entity too large), kill request
            if (body.length > 1e6) {
                response.writeHead(413, {'Content-Type':'text/plain'}).end();
                request.connection.destroy();
            }
        });            // end of data communication: body will contain all the parameters of the query 

        request.on('end',function(){
            var POST = querystring.parse(body);
            // now to get the different parameters use // POST.<field name>  e.g. POST.user
            response.end('Hello, ' + POST.firstname + ' ' + POST.lastname);

        });
    }


}

var server = http.createServer(onRequest);

server.listen(3000);

到目前为止我已经理解了,但是查找和理解此代码的request.on()和querystring.parse()部分时遇到了问题。我会更加清楚地突出显示它们与我混淆的确切部分。

1)request.on()

所以我已经读过request.on('data')会让nodejs为接收一块数据的事件设置一个监听器。所以上面的例子是这一部分:

request.on('data', function (data) {
                body += data;  
                if (body.length > 1e6) {
                    response.writeHead(413, {'Content-Type':'text/plain'}).end();
                    request.connection.destroy();
                }

它将第二个参数作为回调函数,再次获取第一个参数'data'。这就是我所困惑的,它试图用第二个参数做什么?

2)request.on('end')和querystring.parse()

我读到了request.on('end')会让nodejs为数据上传完成的信号设置一个监听器,所以这段代码如下:

request.on('end',function(){
                var POST = querystring.parse(body);
                // now to get the different parameters use // POST.<field name>  e.g. POST.user
                response.end('Hello, ' + POST.firstname + ' ' + POST.lastname);

            }

在request.on('end')内部,我们创建一个名为POST的新变量,并将其设置为querystring.parse(body)body是所有数据组合的前一个变量。它是如何从querystring.parse(body)开始并在其上应用.firstnamePOST.firstname)并访问它的组成部分?

提前致谢。

2 个答案:

答案 0 :(得分:1)

关于你的第一个问题:

  

它采用第二个参数作为回调函数,该函数采用第一个参数&#39;数据&#39;再次。这就是我所困惑的,它在第二个参数中尝试做什么?

所以你在这里做的是定义每次request发起data事件时要调用的侦听器函数。您可以通过以下方式更清楚地看到它:

request.on('data', onChunkReceived)

function onChunkReceived (data) {
  body += data

  if body > 1e6 === 1* Math.pow(10,6) ~~~ 1MB
    if (body.length > 1e6) {
      response.writeHead(413, {'Content-Type':'text/plain'}).end();
      request.connection.destroy();
    }
}

您正在做的是定义一个函数,该函数采用data参数;事件名称和所选参数名称是相同的,不要太挂了;没有理由你无论如何都无法命名它:

request.on('data', onChunkReceived)

function onChunkReceived (chunk) {
  body += chunk

  if body > 1e6 === 1* Math.pow(10,6) ~~~ 1MB
    if (body.length > 1e6) {
      response.writeHead(413, {'Content-Type':'text/plain'}).end();
      request.connection.destroy();
    }
}

......将以完全相同的方式行事。所以:data是事件的名称,你定义了一个函数,当服务器接收到它时,它接收每个数据块;在上面的示例中,函数只是内联的匿名函数,因为我已经重新格式化了它上面的片段,它是一个单独的命名函数。

现在回答你的第二个问题:

  

在request.on(&#39; end&#39;)内部,我们创建一个名为POST的新变量,并将其设置为querystring.parse(body),其中body是所有数据组合的前一个变量。它如何从这个querystring.parse(body)开始并在其上应用.firstname(POST.firstname)并访问它的组件?

querystring.parse方法采用特定格式的字符串,并将其解析为Javascript对象。 Node.js docs on querystring解释它比我能在这里做得好得多。所以,我只能假设您正在使用的示例期望正文将采用特定格式,即form encoded,这意味着它采用以下格式:

firstname=Dan&lastname=Takahashi

当您在该字符串上调用querystring.parse时,您将返回一个看起来像这样的对象:

POST = {
  "firstname": "Dan",
  "lastname": "Takahashi"
}

然后你可以按照上面说的那样解决:POST.firstname这将是&#34; Dan&#34;和POST.lastname,这将是&#34; Takahashi&#34;。

答案 1 :(得分:0)

问题1&amp; 2处理http请求数据流并允许您注入代码以执行自定义活动,例如将流保存到缓冲区/ var以供以后使用。

如果要查询POST参数,只需使用bodyparser节点模块https://github.com/expressjs/body-parser

使用对象点表示法查询参数。例如req.body.form_field_name

body-parser是一个很好的模块,用于快速访问POST / PUT方法中传递的数据。

Express会隐藏原始数据,您需要使用类似于body-parser的模块来访问。请注意,这是正文内容的只读副本。

干杯。

PS如果身体解析器无法满足您的直接需求,请查看

  1. github.com/stream-utils/raw-body
  2. github.com/moscartong/express-rawbody