Node.js:静态服务器

114 阅读2分钟

需要的工具

node-dev

  • 当文件更新是自动重启的node

  • 避免每次改完代码都要重新运行的麻烦

  • 不宜在生产环境使用

ts-node

  • 让node支持直接运行TypeScript代码

  • 不宜在生产环境使用

ts-node-dev

  • 这个工具结合了上面两个工具

  • 可以用TypeScript开发Node.js程序,且会自动重启

  • 不宜在生产环境使用,但非常合适用来学习

image.png

image.png

image.png

创建项目

安装ts-node-dev

yarn global add ts-node-dev或者npm i -g ts-node-dev

步骤

  • yarn init —y

  • 新建index.ts

  • 使用命令行或者WebStorm启动

  • yarn add --dev @types/node安装node声明文件

  • 引入http模块

  • http创建server

  • 监听serverrequest事件(可以简写)

  • server.listen(8888)开始监听8888端口

  • 使用curl -v http://localhost:8888发请求

server 是个什么东西

http.server类的实例

继承net.Server类

用Node.js获取请求内容

get请求

  • request.method获取请求的动词

  • request.url获取请求路径(含查询参数)

  • request.header获取请求头

  • get请求一般没有消息体/请求体

post请求

  • curl -v -d "name=frank" http://localhost:8888

  • request.on('data', fn)获取请求头

  • request.on('end', fn)拼接消息体

(request, response)是啥

找类

  • request是http.IncomingMessage的实例

参考文档

  • response是http.ServerResponse的实例

参考文档

Request

  • 拥有headers、method、url等属性

  • 从stream.Readable类继承了data/end/error事件

  • 为什么不能直接拿到请求的消息体呢?跟TCP有关

Response

  • 拥有getHeader/setHeader/end/write等方法

  • 拥有statusCode属性,可读可写

  • 继承了Stream,目前用不上

image.png

index.ts

import * as http from "http";
import { IncomingMessage, ServerResponse } from "http";
import * as fs from "fs";
import * as p from "path";
import * as url from "url";

const server = http.createServer();
const publicDir = p.resolve(__dirname, "public");
let cacheAge = 3600 * 24 * 365;

server.on("request", (request: IncomingMessage, response: ServerResponse) => {
  const { method, url: path, headers } = request;
  const { pathname, search } = url.parse(path!);

  if (method !== "GET") {
    response.statusCode = 405;
    response.end();
    return;
  }

  //response.setHeader("Content-Type", "text/html; charset=utf-8");
  //  /index.html => index.html

  let filename = pathname!.substring(1);
  if (filename === "") {
    filename = "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);
        });
      } else if (error.errno === -4068) {
        response.statusCode = 403;
        response.end("无权查看目录内容");
      } else {
        response.statusCode = 500;
        response.end("服务器繁忙,请稍后再试");
      }
    } else {
      //添加缓存
      response.setHeader("Cache-Control", `public, max-age=${cacheAge}`);
      //返回文件内容
      response.end(data);
    }
  });
});
server.listen(8888);