文章目录
http.createServer
//main.js
const http = require("http");
const server = http.createServer(function(req,res){
res.writeHead(200,{"Content-Type":"text/html"});
res.end(
"<p>hello world</p>\
<p>have a nice day</p>\
");
})
server.listen(3000,function(){
console.log("listening on *:3000");
});
node main.js
浏览器输入“http://localhost:3000/”,界面显示如下:
其中, req
是http.IncomingMessage实例
,res
是http.ServerResponse实例
,server
是http.Server实例
。
稍微到http
的源码里看下,有这么几行:
//_http_server.js
const net = require('net');
const { OutgoingMessage } = require('_http_outgoing');
const { IncomingMessage } = require('_http_incoming');
function ServerResponse(req) {
OutgoingMessage.call(this);
//...
}
Object.setPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype);
Object.setPrototypeOf(ServerResponse, OutgoingMessage);
function Server(options, requestListener) {
if (!(this instanceof Server)) return new Server(options, requestListener);
//...
}
Object.setPrototypeOf(Server.prototype, net.Server.prototype);
Object.setPrototypeOf(Server, net.Server);
可见ServerResponse
的原型是OutgoingMessage
,或者说,ServerResponse
继承了OutgoingMessage
。同理,Server
继承了net.Server
。
综合起来就有如下继承关系,
server
—>http.Server
—>net.Server
res
—>http.ServerResponse
–>http.OutgoingMessage
req
—>http.IncomingMessage
如果说http
模块代表了应用层
(HTTP协议
),那么net
模块就代表了传输层
(TCP协议
)。
http.Server
—>net.Server
,Node HTTP服务器
就是在Node TCP服务器
基础上构建的。
res.setHeader(name,value)
设置单个响应头的值。
res.setHeader('Content-Type','text/html');
res.writeHead()
向请求发送响应头。注意,并没有真正地发送出去,只是缓存起来了。
可以接收两个参数,也可以接收三个参数,可选参数是状态码说明。
res.writeHead(statusCode,headers)
第一个参数是状态码,像200
,404
,503
等;
第二个参数是一个对象,用来设置响应头, 比如{'Content-Type':'text/html'})
。
res.writeHead(200,{'Content-Type':'text/html'});
res.writeHead(statusCode,statusMessage,headers)
第一个参数是状态码;
第二个参数是状态码说明,是一个字符串,比如'OK'
;
第三个参数是用来设置响应头的对象。
res.writeHead(200,'OK',{'Content-Type':'text/html'});
res.writeHead()与res.setHeader()
-
res.setHeader()
一定要在res.writeHead()
之前调用为什么?到源码里瞧瞧就好了
//_http_server.js
function writeHead(statusCode, reason, obj) {
var headers;
headers = obj;
this._storeHeader(statusLine, headers);
return this;
}
//_http_outgoing.js
OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
if (this._header) {
throw new ERR_HTTP_HEADERS_SENT('set');
}
};
writeHead()
会将响应头缓存在this._header
中,this
就是ServerResponse实例
,即res
。
而setHead()
在设置响应头前,会检查是否有this._header
,如果有,就直接抛出错误"Cannot set headers after they are sent to the client"
。
也就是说,“先writeHead(),后setHeader()”是不允许的。
setHeader()
所有的响应头都将被writeHead()
合并,且writeHead()
优先
res.setHeader('Content-Type','text/plain');
res.setHeader('Server','localhost:3000 (Node)');
res.writeHead(200,{'Content-Type':'text/html'});
res.write()
可以接收一个参数,也可以接收两个参数,也可以接收三个参数。
res.write(data)
data
,响应主体。可以是字符串,也可以是buffer。
res.write("<p>hello world</p><p>have a nice day</p>");
res.write(data,encoding)
data
为字符串时,用encoding
来指定编码方式,默认是utf8
。
res.write("<p>hello world</p><p>have a nice day</p>","utf8");
res.write(data,encoding,callback)
callback
,回调函数。响应头和响应主体发送完毕,该函数会被调用。
前面我们提过,res.writeHead()
只是将设置的响应头缓存起来了,并没有真正地发送出去。实际上,响应头是在res.write()
时发送的。我们来了解下res.write()
是如何工作的。
res.end()
res.end()
和res.write()
差不多,但比res.write()
多了一个作用。它会向服务器发消息,告诉向服务器:所有响应头和响应主体已经发送完毕。服务器只有收到这个消息,才代表真正完成了一次响应。因此,每个响应都必须调用res.end()
。
res.setHeader('Content-Type',"text/plain");
res.writeHead(200,{'Content-Type':'text/html'});
res.write("<p>hello world</p><p>have a nice day</p>","utf8",function(){
console.log("data had been sent");
});
//必须调用res.end(),才代表真正完成了一次响应
res.end();
res.end(data)
,同res.write(data)
res.end(data,encoding)
,同res.write(data,encoding)
res.end(data,encoding,callback)
,同res.write(data,encoding,callback)