http

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/”,界面显示如下:
http://localhost:3000/
其中, reqhttp.IncomingMessage实例reshttp.ServerResponse实例serverhttp.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.ServerNode HTTP服务器就是在Node TCP服务器基础上构建的。

res.setHeader(name,value)

设置单个响应头的值。

res.setHeader('Content-Type','text/html');

res.writeHead()

向请求发送响应头。注意,并没有真正地发送出去,只是缓存起来了
可以接收两个参数,也可以接收三个参数,可选参数是状态码说明。

  • res.writeHead(statusCode,headers)
    第一个参数是状态码,像200404503等;
    第二个参数是一个对象,用来设置响应头, 比如{'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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值