需要的工具
node-dev
-
当文件更新是自动重启的node
-
避免每次改完代码都要重新运行的麻烦
-
不宜在生产环境使用
ts-node
-
让node支持直接运行TypeScript代码
-
不宜在生产环境使用
ts-node-dev
-
这个工具结合了上面两个工具
-
可以用TypeScript开发Node.js程序,且会自动重启
-
不宜在生产环境使用,但非常合适用来学习
创建项目
安装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 -
监听
server的request事件(可以简写) -
server.listen(8888)开始监听8888端口 -
使用
curl -v http://localhost:8888发请求
server 是个什么东西
http.server类的实例
-
根据文档知道http.createServer的返回值的类型
-
所以server是http.Server的实例
-
因此server拥有几个事件和办法
-
其中也就request事件和listen()方法目前能用上
继承net.Server类
-
根据文档知道http.Server继承了net.Server
-
因此server也拥有了几个事件和方法
-
其中也就error事件和address()方法目前能用上
用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,目前用不上
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);