1. 最简单版本GET/POST/…

const http = require('http')
const hostname='localhost' //`127.0.0.1`
const port = 3000
const server = http.createServer((req, res) => {
    if (req.method=='GET'){//处理POST请求
      res.statusCode = 200
      res.setHeader('Content-Type', 'text/plain')
      res.end('你好世界\n')
    }
    else if (req.method=='POST'){//处理POST请求
        ...
    }
})
server.listen(port, () => {
  console.log(`服务器运行在 http://${hostname}:${port}/`)
})
  • 客户端地址 http://localhost:3000

2. 处理HTTP GET请求参数

​ 对于https://cn.bing.com/search?q=baidu&cvid=9ad 这种URL,可从中拆分出pathnamequerystring

  • pathname: /search
  • querystring : ?q=baidu&cvid=0

需引入url模块

const url = require('url');      // 引用url地址模块
server.on('request', (req, res) => {
    if (req.method === "GET") {
        console.log(req.url); // /search?q=baidu&cvid=9ad
        let { query, pathname } = url.parse(req.url, true)
        console.log(pathname);// /search
        console.log(query);// /[Object: null prototype] { q: 'baidu', cvid: '9ad' }
        //...
        if(pathname=='/'){
            res.writeHead(200, { "Content-Type": 'text/html; charset=utf-8' });//注意编码UTF
            // 返回主页内容
            res.end(`<!DOCTYPE html>
			<html><head><meta charset="UTF-8"><title>http</title></head>
			<body>?todo?</body></html>`)
        }
        else if (pathname === '/images/a.jpg') {
            res.writeHead(200, { "Content-Type": "image/jpeg" });
            readFile(__dirname + req.url, (err, buffer) => {
                if (err) throw err;
                res.write(buffer);
                res.end();
            });
        }
    }
 }
 //...
  • 客户端地址 http://localhost:3000/seaarch?q=baidu&id=0,后台打印出query就是一个object。很容易继续处理。

  • 为了保险起见,建议使用pathname进行路由匹配/xx

  • 可以利用mime模块根据路径返回资源的类型

    const mime = require('mime');    // 引用第三方模块 
    //..
    let type = mime.getType(realPath);
    res.writeHead(200, {'content-type': type});
    

3 解析POST数据

const querystring = require('querystring')
server.on('request', (req, res) => {
    //...
    if (req.method == "POST") {
        let postParams = '';
        // 监听参数传输事件
        req.on('data', params => {
            postParams += params;
        });
        // 监听参数传输完毕事件
        req.on('end', () => {
            console.log(postParams)// name=abc&age=123
            console.log(querystring.parse(postParams,"&", "="));// 把字符串格式转换为对象格式
            // [Object: null prototype] { name: 'abc', age: '123' }
        })
    //...
 }

这里需要监听request对象的事件data&on事件,获取所有的post数据,然后用querystring转换为对象格式。

4 静态资源处理

​ 我们有时候需要处理前端静态资源,如html\js\css\png等文件,统一放在public目录下;

const http = require('http');
const { readFile } = require('fs/promises');
const path = require('path')
const url = require('url');  // 引用url地址模块
const mime = require('mime') // npm i mime
const port = 8080;

const server = http.createServer();
server.on("request", async (req, res) => {
  console.log(req.url)
  let { query, pathname } = url.parse(req.url, true)
  // console.log(pathname);// /search
  // console.log(query);// /[Object: null prototype] { q: 'baidu', cvid: '9ad' }
  if (req.method === "GET") {
    if (pathname === "/") {
      pathname = 'index.html'
    }
    pathname = path.join(__dirname, 'public', pathname)
    const type = mime.getType(pathname)
    console.log("GET", pathname, type);
    try {
      res.writeHead(200, {
        "Content-Type": type + ';' + 'charset=utf8'
      });
      let buffer = null;
      if (type.startsWith("text/")) { // 文本文件
        buffer = await readFile(pathname, 'UTF-8')
      } else {// binary文件
        buffer = await readFile(pathname);
      }
      res.write(buffer);
      res.end();
    } catch (err) { // 文件不存在!404.HTML
      console.log("FILE NOT EXIST:", pathname)
      res.writeHead(404, { "Content-Type": 'text/html;charset=utf8' });
      res.end(await readFile('./public/404.html', 'UTF-8'))
      return;
    }
  } else if (req.method === "POST" && req.url === "/register") {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json; charset=utf8');
    res.end(`{code:'ok'}`);
  }
});
const host = "localhost";
server.listen(port, () => {
  console.log(`服务器运行在 http://${host}:${port}/`);
});

参考