Node 基础 4 :HTTP 模块

91 阅读2分钟

创建项目

1、yarn init -y -y 表示默认 yes;

2、新建 index.ts;

3、启动 WebStorm ,yarn add --dev @types/node,安装 node 模块的声明文件,这样 ts 才知道 node 有哪些模块;

4、引入 http 模块;

5、用 http 创建 server;

6、监听 server 的 request 事件;

7、server.listen(8888) 开始监听 8888 端口;

8、使用 curl -v http://localhost:8888 发请求。

//index.ts

import * as http from 'http'; 

const server = http.createServer();  //创建 server

server.on('request',(request,response)=>{  // 监听请求
  console.log('有人发请求');  //当有人向服务器发请求时,服务器端打印'有人发请求'
  response.end('响应结束了')  //结束响应,请求发起者得到内容为‘响应结束了’的响应内容;
})

server.listen(8888)  //监听本机的 8888 端口,不监听的话,之前的 server.on('request',()=>{}) 写了也没用;

发请求

console.log(request.constructor);  //查看 request 是由谁构造出来的

发 get 请求

curl -v http://localhost:8888/yyy   //加 -v 会将请求内容显示在终端

发 post 请求

curl -v -d 'name:jason'  http://localhost:8888/yyy  //加 -d 表示发送 post 请求

获取 post 请求的消息体

const array = [];
request.on('data', (chunk) => {  //请求上传的过程中会不断触发 data 事件,获取消息体
  array.push(chunk);  //chunk 是一小段代码,属于 Buffer 类
});
request.on('end', () => {  //上传结束,拼接消息体
  const body = Buffer.concat(array).toString();
  console.log('body');
  console.log(body);
  response.end('hi');
});

(request,response)是什么

  • 找类 1、根据文档,request 是 http.IncomingMessage 的实例

2、根据文档,response 是 http.ServerResponse 的实例

  • Request 1、拥有 headers、method、url 等属性;

2、从 stream.Readable 类继承了 data/end/error 等事件;

3、因为 TCP 规定,请求上传时,每次只能传一小段数据,所以无法直接拿到请求的消息体;

  • Response 1、拥有 getHeader/setHeader/end/write 等方法;

2、拥有 statusCode 属性,可读可写;

3、继承了 Stream ;

request.on('end', () => {
  response.setHeader('x-jason','little funny')
  console.log(response.getHeader('x-jason'));
  response.statusCode = 404
  response.write('1')   //每次响应的时候都会执行
  response.write('23')  // 可以调用多次
  //响应一张图片,要先设置 Content-Type ,然后 write
  response.setHeader('Content-type','image/png')
  response.write(ImageData)
  response.end();
});

根据 url 返回不同的文件

import * as p from 'path';  引入 node 的 path 模块
const publicDir = p.resolve(__dirname, 'public');  // __dirname 表示当前文件所在目录
server.on('request', (request, response) => {
  const {method, url, headers} = request;
  switch (url) {
    case '/index.html':
      response.setHeader('Content-Type','text/html;charset=utf-8')
      fs.readFile(p.resolve(publicDir, 'index.html'), (error, data) => {
        if (error) throw error;
        response.end(data.toString());
      });
      break;
 }
}) 

处理查询参数

使用 new URL 类,

const {method, url:path, headers} = request;

//第一个参数为 相对路径时,必须将 base url 作为第二个参数
const {pathname,search} = new URL(`${path}`,'http://localhost:8888/')  
//console.log(pathname);
switch (pathname) {
  case '/index.html':
}

处理不存在的文件

fs.readFile(p.resolve(publicDir, filename), (error, data) => {
  if (error) {
    console.log(error);
    if (error.errno === -4058) {
      response.statusCode = 404;
      fs.readFile(p.resolve(publicDir, '404.html'), (error, data) => {
        response.end(data);
      });
    }
  
//在 public 文件夹右键,设为 resource root。否则,当访问不存在的文件时
//如访问 xxx/ccc/aa.html,图片路径为 http://localhost:8888/xxx/ccc/images/404.jpg ,而不是 public/images/404.jpg

//public/images/404.html  
<body>
你要找的内容不存在
<p>
    <img src="/images/404.jpg">   //src 的路径前面加 /
</p>
</body>