Skip to content

HTTP模块 ​

net模块已经可以实现http请求和响应了,但是如果直接使用net模块来搭建HTTP请求未免过于麻烦,我们不太会直接使用,更加常见的是使用HTTP模块,HTTP模块是建立在net模块上的,使用http模块之后,我们无需手动管理socket,无需手动组装消息格式.

请求 ​

http模块发送请求通过http模块下的request方法来发送,第一个参数是发送请求的地址,第二个参数为配置对象,这个请求和fetch请求很类似,基本一看就懂,第三个参数为回调函数,当拿到响应结果后,会调用这个回调函数,并给我们传入响应结果,响应结果为serverResponce对象.

使用request发送请求的时候,必须配置消息体,消息体的配置和ajax不一样,request函数返回一个request对象,这个对象是一个ClientRequest对象,这个对象就是一个可写流,我们可以向里面直接写入消息体,写完后调用request.end(),就完成了写入操作,如果没有消息体,我们可以直接调用end方法来结束写入.

javascript
const http = require("http");
const request = http.request(
  "http://www.baidu.com",
  {
    method: "GET",
  },
  (resp) => {
    console.log(resp.statusCode);
  }
);
request.end();

回调函数里面这个response对象里面除了可以获取状态码,还可以获取响应头

这个resp是IncomingMessage类的对象,这个对象是一个读取流,我们除了可以在他身上直接拿到一些属性外,我们还可以对他进行读取流的操作,来获取响应体.

javascript
const http = require("http");
const request = http.request(
    "http://www.baidu.com",
    {
        method: "GET",
    },
    (resp) => {
        resp.on("data", (chunk) => {
            console.log(chunk.toString("utf-8"));
        });
    }
);
request.end();

这就实现了整个请求响应过程,比起net模块,http模块显然更加方便.

响应 ​

显然,我们学习node并不是为了请求服务器,尽管node可以作为客户端去请求服务器,但我们客户端一般是浏览器,不怎么会去用node写

要搭建一个http服务器,需要调用http模块的createServer方法,第一个参数为配置对象,第二个参数为监听到请求的处理函数,这个处理函数有两个参数,一个是request对象,一个是response对象,request对象是一个IncommingMessage对象,response对象是一个ServerResponse对象,request也就是请求的对象

不管是作为客户端还是服务端,incommingMessage对象都是别人给我的对象,作为客户端,服务端给我的响应结果就是一个incommingmessage,作为服务端,客户端给我的就是incommingmessage,只需要这个对象是一个可读流即可,别人给我的当然必须是一个可读流,我就能知道别人给我的是啥

总结一下

画板

这个createServer方法会返回一个server对象,这个server就类似前面net模块的那个server,可以用listen监听端口

javascript
const http = require("http");
const server = http.createServer(
    {
        //可选参数,可以不填
    },
    (request, response) => {
        // 当有请求来了,会调用这个函数
        console.log("来了一个请求");
        console.log(request.url);
        console.log(request.headers); //可以获取请求头
        console.log(request.method); //可以获取请求方法
        //可以获取请求体,请求体是一个流
        let body = "";
        request.on("data", (chunk) => {
            body += chunk.toString("utf-8");
            //每次读取,写入body
        });
        request.on("end", () => {
            //读完之后,输出body
            console.log(body);
        });

        //可以对客户端进行响应
        response.setHeader("a", "1"); //可以设置响应头
        response.write("hello");
        response.end(); //结束
    }
);
server.listen(9527); //开始监听
server.on("listening", () => {
    // 开始监听时,调用这个函数
    console.log("开始监听");
});

此时就可以拿到服务器的响应结果

可以看到在响应的时候,http模块给我们添加了一些响应头,我们可以通过response.removeHeader(name)方法来删除响应头,同时我们也可以通过response.statusCode设置响应码

当然这个也偏向底层,我们更常用一些第三方库会更加方便,这些模块的要求都是可以根据文档写出来东西即可

下面我们就可以做一个静态资源的服务器了

javascript
const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("fs");
const server = http.createServer(
    {
        //可选参数,可以不填
    },
    async (request, response) => {
        // 当有请求来了,会调用这个函数
        console.log("来了一个请求");
        const urlObj = url.parse(request.url); //当请求来了,解析请求地址
        const src = path.resolve(__dirname, urlObj.pathname.substring(1)); //获取需要访问的数据

        try {
            const data = await fs.promises.readFile(src); //读取文件内容
            response.write(data); //写入响应体
            response.end();
        } catch (e) {
            //如果有问题,返回404
            response.write(`
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Document</title>
            </head>
            <body>
                <h1>404error</h1>
            </body>
            </html>
            `);
            response.end();
        }
    }
);
server.listen(9527); //开始监听
server.on("listening", () => {
    // 开始监听时,调用这个函数
    console.log("开始监听");
});

以笔记为镜,可以知得失