Node之HTTP服务器创建服务器和获取客户端请求数据

创建HTTP服务器

在Node.js中,可以很方便地创建一个HTTP服务器,只需调用http模块中的create Server方法即可

var server=http.createServer([requestListener])

在createServer方法中,可以使用一个可选参数,参数值为一个回调函数,用于指定当接收到客户端请求时所需执行的处理,该回调函数的指定方法如下所示。

function (request,response) {
//回调函数代码略
}

  • request:代表一个客户端请求
  • response:代表一个服务器端响应对象

createServer方法返回被创建的服务器对象,如果不在createServer方法中使用参数,也可以通过监听该方法创建的服务器对象的request事件(当接收到客户端请求时触发),并且指定该事件触发时调用的回调函数的方法来指定当接收到客户端请求时所需执行的处理,代码如下所示(代码中的server代表一个HTTP服务器)。

server.on('request',function(request,response){
    //回调函数代码略
});

在创建了HTTP服务器后,需要指定该服务器所要监听的地址(可以为一个IP地址,也可以为一个主机名)及端口,这时,可以使用该HTTP服务器的listen方法

server.listen(port,[host],[backlog],[callback])
  • port:端口号
  • host:主机
  • backlog:最大连接数
  • callback:回调

也可使用listening事件实现

server.on('listening',function(){
    //回调函数代码略
});

创建一个服务器完整示例:

var http = require('http');
var server=http.createServer(function (req, res) {
    //暂不指定接收到客户端请求时的处理
}).listen(1337, "127.0.0.1",function(){
    console.log('服务器端开始监听。');
});

close()关闭服务器

server.close();

可以监听服务器被关闭以后

server.on('close',function(){
    //回调函数代码略
});

监听服务器错误信息

server.on('error', function (e) {
    if (e.code == 'EADDRINUSE') {//当地址及端口被占用时错误代码为'EADDRINUSE'
        //可以在此处指定当地址及端口被占用时所需执行的处理
    }
});

长链接

在默认情况下,客户端和服务器端每进行一次HTTP操作,都将建立一次连接,客户端与服务器端之间的交互通信完成后该连接就中断。在HTTP1.1中,添加了长连接支持。如果客户端发出的请求头信息或者服务器端发出的响应头信息中加入了“Connection:keep-alive”信息,则HTTP连接将继续保持,客户端可以继续通过相同的连接向服务器端发出请求。

在Node.js中,当客户端与服务器端建立连接时,触发HTTP服务器对象的connection事件,可以监听该事件并在该事件触发时调用的回调函数中指定当连接建立时所需要执行的处理

server.on('connection',function(socket){
    //回调函数代码略
});

在该回调函数中可以使用一个参数,参数值为服务器端用于监听客户端请求的socket端口对象。

设置服务器的超时时间

可以使用HTTP服务器的setTimeout方法来设置服务器的超时时间。当该超时时间超过之后,客户端不可继续利用本次与HTTP服务器建立的连接,下次向该HTTP服务器发出请求时必须重新建立连接。

server.setTimeout(msecs, callback)
  • mecs:参数值为一个整数,用于设置服务器的超时时间,单位为毫秒,可以通过将该参数值设置为0的方法取消服务器的超时处理。
  • callback:用于设置当服务器超时时调用的回调函数,在该回调函数中可以使用一个参数,参数值为服务器端用于监听客户端请求的socket对象。
server.on('timeout',function(socket){
    //回调函数代码略
});

获取客户端请求信息

HTTP服务器接收到客户端请求时调用的回调函数中的第一个参数值为一个http.IncomingMessage对象,该对象用于读取客户端请求流中的数据,因此,当从客户端请求流中读取到新的数据时触发data事件,当读取完客户端请求流中的数据时触发end事件。当该对象被用于读取客户端请求流中的数据时,该对象拥有如下所示的一些属性。

  • method:该属性值为一个字符串,字符串值为客户端向服务器端发送请求时使用的方法,例如“GET”、“POST”、“PUT”或“DELETE”。
  • url:该属性值为客户端发送请求时使用的URL参数字符串,例如“/”、“/user/1”、“/post/new/?param=value”。该属性为一个非常重要的属性,通常用来判断客户端请求的页面及需要执行的处理。
  • headers:该属性值为客户端发送的请求头对象,其中存放了客户端发送的所有请求头信息,包括各种cookie信息以及浏览器的各种信息。
  • httpVersion:该属性值为一个字符串,字符串值为客户端发送的HTTP版本,可能的值为“1.1”或“1.0”。
  • trailers:该属性值为客户端发送的trailer对象。该对象中存放了客户端附加的一些HTTP头信息,该对象被包含在客户端发送的请求数据之后,因此只有当http.IncomingMessage对象的end事件触发之后才能读取到trailer对象中的信息。
  • socket:该属性值为服务器端用于监听客户端请求的socket对象。

获取请求数据

var http = require('http');
var fs = require('fs');
var server=http.createServer(function (req, res) {
    if(req.url!=="/favicon.ico"){
        req.on('data',function(data){
        console.log('服务器端接收到数据:'+decodeURIComponent(data));
        });
        req.on('end',function(){
        console.log('客户端请求数据已全部接收完毕。');
        });
    }
    res.end();
}).listen(1337, "127.0.0.1");

转换URL字符串与查询字符串

在Node.js中,提供了一个url模块与一个QueryString模块,分别用来转换完整URL字符串与URL中的查询字符串。

在一个完整的URL字符串中,从“?”字符之后(不包括“?”字符)到“#”字符之前(如果存在“#”字符)或者到该URL字符串结束(如果不存在“#”字符)的这一部分称为查询字符串,例如在“http://google.com/user.php?userName=Lulingniu&age=40&sex=male#hash”这个URL字符串中,“userName=Lulingniu&age=40&sex=male”这个部分称为一个查询字符串。

Query String模块中的parse方法

可以使用Query String模块中的parse方法将该字符串转换为一个对象

querystring.parse(str,[sep],[eq],[options])
  • str:用于指定被转换的查询字符串;
  • sep:用于指定该查询字符串中的分割字符,默认参数值为“&”
  • eq:用于指定该查询字符串中的分配字符,默认参数值为“=”
  • options:options参数值为一个对象,可以在该对象中使用一个整数值类型的maxKeys属性来指定转换后的对象中的属性个数,如果将maxKeys属性值设定为0,其效果等于不使用maxKeys属性值。

Query String模块中的stringify方法

可以使用Query String模块中的stringify方法将对象转换为一个查询字符串

querystring.stringify(obj,[sep],[eq])
  • obj:用于指定被转换的对象;
  • sep:用于指定查询字符串中所使用的分割字符,默认参数值为“&”;
  • eq:用于指定查询字符串中使用的分配字符,默认参数值为“=”。

url.parse()

在url模块中,可以使用parse方法将URL字符串转换为一个对象,根据URL字符串中的不同内容,该对象中可能具有的属性及其含义如下所示。

  • href:被转换的原URL字符串。
  • protocol:客户端发出请求时使用的协议。
  • slashes:在协议与路径中间是否使用“//”分隔符。
  • host:URL字符串中的完整地址及端口号,该地址可能为一个IP地址,也可能为一个主机名。
  • auth:URL字符串中的认证信息部分。
  • hostname:URL字符串中的完整地址,该地址可能为一个IP地址,也可能为一个主机名。
  • port:URL字符串中的端口号。
  • pathname:URL字符串中的路径,不包含查询字符串。
  • search:URL字符串中的查询字符串,包含起始字符“?”。
  • path:URL字符串中的路径,包含查询字符串。
  • query:URL字符串中的查询字符串,不包含起始字符“?”,或根据该查询字符串而转换的对象(根据parse方法所用参数而决定query属性值)。
  • hash:URL字符串中的散列字符串,包含起始字符“#”。
url.parse(urlStr,[parseQueryString])
  • urlStr:用于指定需要转换的URL字符串;
  • parseQueryString:为一个布尔类型的参数,当参数值为true时,内部使用Query String模块将查询字符串转换为一个对象,参数值为false时不执行该转换操作,默认参数值为false。

url.format()

可以使用url模块中的format方法将URL字符串经过转换后的对象还原为一个URL字符串。

url.format(urlObj)

url.resolve()

可以使用resolve方法将两个方法结合成为一个路径

url.resolve(from,to
  • from:起点路径字符串
  • to:参考路径字符串

在resolve方法中,使用两个字符串类型的参数,其中第一个参数为起点路径字符串,第二个参数为参考路径字符串。这两个路径既可为相对路径,也可为绝对路径。该方法返回转换后的路径。

在结合路径时,以第一参数值为起点路径,执行如下所示的转换规则。

  • 如果起点路径为网络路径,参考路径为非网络路径的绝对路径,则返回路径为网络根目录+参考路径。
  • 在其他情况下,如果参考路径为绝对路径,则返回路径为该参考路径。
  • 如果起点路径为一个不以“/”字符结尾的根目录且参考路径为相对路径,则返回路径为:起点路径+“/”+参考路径中去除开头的“./”字符或“…/”字符(如果存在的话)后的文字。如果起点路径为一个以“/”字符结尾的根目录且参考路径为相对路径,则返回起点路径+参考路径中去除开头的“./”字符或“…/”字符(如果存在的话)后的文字。
  • 如果起点路径为一个不以“/”字符结尾的子目录且参考路径为相对路径,同时开头字符不为“./”或“…/”,则返回路径为:起点路径的上层目录+“/”+参考路径。如果起点路径为一个以“/”字符结尾的子目录且参考路径为相对路径,同时开头字符不为“./”或“…/”,则返回路径为:起点路径的上层目录+“/”+参考路径。
  • 如果起点路径为一个不以“/”字符结尾的子目录且参考路径为相对路径,同时开头字符为“./”,则返回路径为:起点路径的上层目录+“/”+参考路径中去除开头的“./”字符后的文字。如果起点路径为一个以“/”字符结尾的子目录且参考路径为相对路径,同时开头字符为“./”,则返回起点路径+参考路径中去除开头的“./”字符后的文字。
  • 如果起点路径为一个不以“/”字符结尾的子目录且参考路径为相对路径,同时开头字符为“…/”,则返回路径为:起点路径的上层目录的上层目录+“/”+参考路径中去除开头的“…/”字符后的文字。如果起点路径为一个以“/”字符结尾的子目录且参考路径为相对路径,同时开头字符为“…/”,则返
    回起点路径的上层目录+参考路径中去除开头的“…/”字符后的文字。
发布了139 篇原创文章 · 获赞 46 · 访问量 80万+

猜你喜欢

转载自blog.csdn.net/m0_37938910/article/details/103812769