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

2022-10-10 14:18:25

表单提交过来的数据有两种方法,一种是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!?

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

Node的快就在于它处处存在异步,存在回调,基于观察者模式于一身的美男子。
这里我不得不说一下Node的异步运行机制。

整个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);

另外:

nodejs对于post请求和get请求的获取方式不一样。

1.get请求

用url模块处理req.url就能够获取get参数

var url = require("url");
//params就是get方法携带的参数
var params = url.parse(req.url, true).query;

2.post请求

Post由于它的重量,所以不可能说接收就接收,它会存储接入中和接入完成两种状态,两种状态对应着回调方法,即,当然数据处于接入中状态时,处理一种流程;当数据接入完成后,处理另一种流程。

   var postData = ""; 
    // 数据块接收中
    req.addListener("data", function (postDataChunk) {
        postData += postDataChunk;
    });
    // 数据接收完毕,执行回调函数
    req.addListener("end", function () {
        var params = querystring.parse(postData);
        console.log(params);
    });

以上node事件监听当中的on和addListener的区别

没有区别,EventEmitter.prototype.on = EventEmitter.prototype.addListener;

转载于:
————————————————
版权声明:本文为CSDN博主「小辣抓」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/HaoDaWang/article/details/53024122


关于  js  异步的文章  请见这篇博客:

https://zhuanlan.zhihu.com/p/78816710

https://blog.csdn.net/qq_41601836/article/details/117230359

乐于分享

  • 作者:万无引力-
  • 原文链接:https://blog.csdn.net/qq_41601836/article/details/117230218
    更新时间:2022-10-10 14:18:25