创建项目
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>