上一篇《《Node.js权威指南》:如何创建HTTP服务器》中概括的介绍了创建HTTP服务器的套路,包括创建http服务器对象,用服务器对象监听客户端连接事件、错误事件和服务器关闭事件等,整体示例如下:
代码语言:javascript复制const http = require( "http" );
const event = require( "events" );
class myEmitter extends event.EventEmitter{};
let emitter = new myEmitter();
// 调用http模块的createServer()方法,传入回调函数,方法返回创建的HTTP服务器对象
let app = http.createServer( function ( req, res ) {
// req 客户端请求对象
// res 服务器端响应对象
res.writeHead( 200, { "Content-type": "text/html" } );
res.write( "<head><meta charset='utf8'></head>" );
res.end("你好nitx");
} )
// 服务器监听 error 事件
app.on( "error", function ( e ) {
if( e.code === "EADDRINUSE" ){
console.log( "地址及商品被占用。" );
}
} )
// 服务器对象监听 客户端连接 事件
app.on( "connection", function ( socket ) {
console.log( "客户端连接已建立。" );
} )
// 服务器对象监听 服务器关闭 事件
app.on( "close", function () {
console.log( "服务器已关闭。" );
} )
// 主动设置定时器 2秒后 触发 服务器对象的close()方法关闭服务器
setTimeout( function () {
emitter.emit( app.close() );
}, 2000 )
// 服务器对象监听 1338 商品,host和backlog参数默认
app.listen( 1338, ()=>{ console.log( "service is running at port 1338." ); } );
在上例中回顾下nodejs中的事件监听,nodejs用于实现各种事件处理的events模块中,定义了一个EventEmitter
类。所有可能触发事件的对象都是一个继承了EventEmitter
类的子类的实例对象。
获取客户端请求信息
HTTP服务器接收到客户端请求时调用的回调函数中的第一个参数值是一个http.IncomingMessage
对象,该对象用于读取客户端请求流中的数据。当从客户端请求流中读取到新数据时触发data
事件,当读取完客户端请求流中的数据时触发end事件。当该对象被用于读取客户端请求流中的数据时,该对象拥有如下属性:
method
:该属性值是一个字符串,字符串值为客户端向服务器端发送请求时使用的方法,如GET
、POST
、PUT
、DELETE
等。url
:该属性值是客户端发送请求时使用的url参数字符串,例如/
、/abc/1
、post/new?param=value
等。这个属性非常重要,通常用来判断客户端请求的页面和需要执行的处理。headers
:该属性值是客户端发送的请求头对象,存放客户端发送的所有请求头信息,包括cookie信息和浏览器的各种信息。socket
:该属性值是服务器端用于监听客户端请求的socket对象。
const http = require( "http" );
let app = http.createServer( function ( req, res ) {
console.log( `客户端请求方法为:${req.method}` );
console.log( `客户端请求所用url字符串为:${req.url}` );
console.log( `客户端请求头对象为:${req.headers}` );
console.log( `客户端请求所用HTTP版本为:${req.httpVersion}` );
console.log( `客户端请求的socket对象为:${req.socket}` );
res.writeHead( 200, { "Content-type": "text/html" } );
res.write( "<head><meta charset='utf8'></head>" );
res.end( "大家好,我是nitx" );
} )
app.listen( 1339, ()=>{ console.log( "service is running at port 1339." ); } )
当客户端请求用http://localhost:1339/abc?param=value
这个url请求时,上例的打印结果为:
前面说了当HTTP服务器对象createServer()方法中回调函数第一个参数http.IncomingMessage
对象从客户端请求数据流读到新数据时会触发data
事件,读完数据时会触发end
事件,下面就来个示例看下这两个事件:
// app.js
const http = require( "http" );
let app = 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();
} )
app.listen( 1335, "127.0.0.1", ()=>{ console.log( "service is running at port 1335." ); } )
// index.html
<body>
<form action="http://127.0.0.1:1335" method="POST">
<input type="text" name="name">
<input type="number" name="age">
<input type="submit" value="提交">
</form>
</body>
在index.html
中进行表单数据提交后,app.js
控制台打印结果为: