Node.js 获取GET、POST提交的数据

表单提交过来的数据有两种方法,一种是GET方式提交,这种提交方法会把表单需要传输的数据写在url上,一起带过去,另一种是POST方式提交,POST方式提交会把表单数据携带在request请求正文中传递过去。

针对这两种不同的提交方法,node里也有两种不同的处理方法。先看看如果用GET方式提交,我们该怎么去处理

获取GET方式提交的数据

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <form action="http://localhost:9998" method="get">
            <input type="text" name="user" value="" />
            <input type="password" name="passw" value="" />
            <input type="submit" value=""/>
        </form>
    </body>
</html>

index.html只是一个简单的表单网页,两个输入框用作用户的账号和密码输入,还有一个submit用来提交。

下面是node实现

GETServer.js

var http = require("http");
var url = require("url");

function onRequest(req,resp){ 
    console.log(url.parse(req.url,true).query);
    //返回响应
    resp.writeHead(200,{
  "ContentType":"text/html;charset=utf-8"});
    resp.end();
}

//创建server
http.createServer(onRequest).listen(9998);

这样的话就获取到了表单使用GET方式提交过来的数据
其中req.url 是指req提交过来的url的路由
但是我们会发现一个问题,我们看一下console的打印情况。

{ user: 'asda', passw: 'asddasd' }
{ }

我们会发现打印了两行,第二行被打印出了一个空的JSON对象。这是怎么回事呢,听老衲缓缓道来。

在第一次request请求的时候,客户端会发送一个隐式的请求给服务器,这个请求就是为了获取到网页的图标(就是每个网页打开后Title旁边的那个小图标),所以,当我们提交表单数据的时候,实际是触发了两次请求,第一次请求favicon.ico ,第二次提交数据,所以我们打印出来的结果就是两个对象。

so?那么我们应该怎样去处理它呢?我们需要在服务端过滤掉请求favicon.ico的请求。
只需加上一段这样的if就行

if(req.url != "/favicon.ico"){
    console.log(url.parse(req.url,true).query);
}

这样的话我们再看一下console的打印结果是不是正常了

{ user: 'asda', passw: 'asddasd' }

获取POST方式提交的数据

开头我也说过了,用POST方式提交的数据会附带在请求正文里面,所以我们需要获取到附带在request正文里的信息,那具体是怎么做呢?

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <form action="http://localhost:9998" method="post">
            <input type="text" name="user" value="" />
            <input type="password" name="passw" value="" />
            <input type="submit" value=""/>
        </form>
    </body>
</html>

这里只做了简单的修改,把method 从get改为post

POSTServer.js

/** * New node file */

var http = require("http");
var queryString = require("querystring");

function onRequest(req,resp){
    //过滤掉favicon请求
    if(req.url != "/favicon.ico"){
        //post请求 获取表单数据
        var obj = null;
        var currentData = "";
        req.on("data",function(data){
            currentData += data;
            obj = queryString.parse(currentData);
        });
        console.log(obj);
        resp.writeHead(200,{
  "ContentType":"text/html;charset=utf-8"});
        resp.end();
    }
}


//创建server
http.createServer(onRequest).listen(9998);

上面的querystring.parse就能直接把获取到的数据转换成JSON对象。
接下来我们来看看控制台是怎么打印的

null

what!?
《Node.js 获取GET、POST提交的数据》

为什么是null!?
这就说明如果要学习Node就得改掉我们写java ,写C/C++ 那些非异步的语言的编程习惯,因为这里的原因之所以是Null是因为Node本身机制的原因

Node的快就在于它处处存在异步,存在回调,基于观察者模式于一身的美男子

这里我不得不说一下Node的异步运行机制。
下面我画一张丑图仅供大家参考。

《Node.js 获取GET、POST提交的数据》

看不清的朋友右键查看原图把。
画的有点丑大家凑合着看,我来简单的说明一下这幅图。

整个Node程序在执行的过程中,遇到了sync Event 也就是同步事件,然后解释器会把它交给一个叫做事件栈(Event Stack)的数据结构,这个栈会不断的去push同步代码,然后执行完毕后pop出来。当程序遇到异步事件(async Event)的时候,会把它交给别的地方来处理,处理完毕后将结果返回至事件队列(Event Queue),当Event Stack空闲的时候,就会让一个Loop来挨个挨个将事件队列中的事件取出来,放入事件栈里执行回调。

这时我们就可以解释为什么是null了,因为request 绑定了一个名为data的异步事件,但是我们console.log(obj);是sync的,所以解释器会先打印出obj的值,再去事件队列中取出来放到事件栈中去执行回调,虽然我们代码顺序是先赋值,再打印,而结果却出乎我们意料,是先打印再赋值,对于这种情况的解决办法,我们初步可以调用setTimeout的方法来解决它。setTimeout() 是一个延迟执行的函数,用它可以将我们的console.log(obj);放入队列尾,这样的话,我们就能够实现先赋值再打印了,当然这样会降低程序的效率。

我们来修改一下程序的代码

POSTServer.js

/** * New node file */

var http = require("http");
var queryString = require("querystring");

function onRequest(req,resp){ 
    //过滤掉favicon请求
    if(req.url != "/favicon.ico"){
        //post请求 获取表单数据
        var obj = null;
        var currentData = "";
        req.on("data",function(data){ 
            currentData += data;
            obj = queryString.parse(currentData);
        });
        setTimeout(function(){ 
            console.log(obj);
        },1000);
        resp.writeHead(200,{
  "ContentType":"text/html;charset=utf-8"});
        resp.end();
    }
}


//创建server
http.createServer(onRequest).listen(9998);

这样的话我们就能看到console打印出来的正常的结果。

{ user: 'asda', passw: 'asddasd' }

完美处理POST、GET请求

接下来我们结合两种方法来实现不管POST,GET提交的方式我们都能处理。

GETPOSTServer.js

/** * New node file */

var http = require("http");
var url = require("url");
var queryString = require("querystring");

function onRequest(req,resp){ 
    //过滤掉favicon请求
    if(req.url != "/favicon.ico"){
        //需要的json对象
        var obj = null;
        //区分get post 请求
        if(req.method == "GET"){
            obj = url.parse(req.url,true).query;
        }
        else{
            //post请求 获取表单数据
            var currentData = "";
            req.on("data",function(data){ 
                currentData += data;
                obj = queryString.parse(currentData);
            });
        }
        //添加进事件队列
        setTimeout(function(){ 
            console.log(obj);
        },1000);
        write(resp);

    }
}

function write(resp){ 
    resp.writeHead(200,{
  "ContentType":"text/html;charset=utf-8"});
    resp.end();
}


//创建server
http.createServer(onRequest).listen(9998);

如果大家发现本篇博文有任何错误,都可以在回复区反馈给我。我会及时改正,共勉!

    原文作者:小辣抓
    原文地址: https://blog.csdn.net/HaoDaWang/article/details/53024122
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞