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