4Node.js Web 服务器创建和静态文件处理指南(上)

78 阅读4分钟

一. 一些有用的工具

  • node-dev
    • 当文件更新时自动重启的node
    • 避免每次改完代码都要重新运行的麻烦
    • 不宜在生产环境使用
  • ts-node
    • 让node支持直接运行TypeScript代码
    • 不宜在生产环境使用
  • ts-node-dev,这个结合了上面两个工具
    • 这个工具结合了上面两个工具
    • 可以用TypeScript开发Node,js程序,且会自动重启
    • 不宜在生产环境使用,但非常适合用来学习
yarn global add ts-node-dev
  • WebStorm 自动格式化

    • Reformat Code设置为Ctrl+L或者其他键位
    • 可以快速帮你格式化TS/JS代码
  • WebStorm自动写代码

    • Complete Current Statement设为Ctrl+Enter
    • Show Context Actions设为Alt+Enter
    • 把冲突的键位改成其他快捷键,当然你可以设为其他键位,这只是我的习惯
  • VSCode配置

    • 开启自动保存,开启保存时自动格式化(有些人不喜欢)
    • 当然也可以Shift+Alt+F手动格式化
    • Quick Fix默认快捷键Ctrl+句号(功能稍弱)
  • WebStorm Git配置

    • 把WebStorm的git路径设置为cmder里的
    • 示例:`D:Fang Software\cmder\vendor\git-for-windows\bin\git.exe

  • 好处是统一管理统一配置
  • VSCode Git配置 在settings.json里添加
"git.enabled":true,
"git.path":"D:\\...\\git-for-windows\\cmd\\git.exe",
"terminal.integrated.shell.windows":"D:\\...\\git-for-windows\\bin\bash.exe",
  • 目的是让VSCode使用cmder里的git和bash

  • 你如果没装cmder就自行修改为其他路径

  • curl

    • GET请求:curl -v url
      • POST请求:curl -v -d "name=frank" url
    • 设置请求头:-H 'Content-Type:application/json'
    • 设置动词:-X PUT
    • JSON请求:curl-d '{"name":"bob"}' -H 'Content-Type:application/json' url,后面会用到curl来构造请求

二. 新建项目

  • 创建一个文件夹,比如叫做node-server-1
  • 运行yarn init -y,变成npm的包
  • 新建index.ts
  • 使用命令行或者WebStorm启动
  • yarn add --dev @types/node安装node声明文件
  • 引入http模块(WebStorm自动导入)
  • 用http创建server(WebStorm自动命名)
  • 监听server的request事件(可以简写)
  • server.listen(8888)开始监听8888端口
import * as http from 'http';

const server = http.createServer();

server.on('request', () => {
  console.log('有人请求了');
});
server.listen(8888);
  • 使用curl -v http://localhost:8888发请求,此时服务器控制台会有响应
  • 修改代码此时接收到请求会返回hi
import * as http from 'http';

const server = http.createServer();

server.on('request', (request, response) => {
  console.log('有人请求了');
  response.end('hi')
});
server.listen(8888);

三. 详解上述代码啊

  • server是什么,
    • 我们通过点击http.createServer()查看源代码,它的返回值是一个Server类的实例

  • 我们可以从文档上的看到这个实例是什么,我们目前用到了这个实例的request和listen方法

  • 同时我们也可以知道http.Server继承自net.Server,因此它也有net.Sever的几个事件和方法,目前error事件和address()方法是用得上的

  • 实现根据不同的请求路径,提供不同的响应

    • 通过httpVersion和url来得到http版本和请求路径
server.on('request', (request, response) => {
  console.log(request.httpVersion)
  console.log(request.url)
  response.end('hi')
});
  • 通过request获取请求方式,路径和请求头信息
server.on('request', (request, response) => {
  console.log(`request.method`)
  console.log(request.method)
  console.log(`request.url`)
  console.log(request.url)
  console.log(`request.headers`)
  console.log(request.headers)
  response.end('hi')
});
  • 构造post请求,curl -v -d "name=frank" http://localhost:8888,此时我们没拿到请求携带的数据,接下来我们看下如何拿到post携带的数据

四. 如何拿到post的数据

  • 我们可以通过监听data事件来获取,我们通过文档可以得知request继承自http.IncomingMessage
  • http.IncomingMessage继承自<stream.Readable>,其data事件来自<stream.Readable>
  • 而这个data如果是2mb的文件那么,每次上传一点,我们需要将这个data数据收集起来放到一个数组
  • end表示没有数据可供消费了,也就是上传完成了,这种方式只要服务器内存够就算上传1g的文件也可以处理
import * as http from 'http';

const server = http.createServer();

server.on('request', (request, response) => {
  const array = [];
  request.on('data', (chunk) => {
    array.push(chunk)
  });
  request.on('end', () => {
    const body = Buffer.concat(array).toString();
    console.log('body');
    console.log(body);
    response.end('hi');
  });
});
server.listen(8888);

五. 学习response对象

  • response.statusCode = 404,修改响应码
  • response.setHeader('X-frank', 'I am Frank'),可以设置响应头
  • 可以使用write多次设置相应内容之后,再一起返回

response.write('1\n')
response.write('2\n')
response.write('3\n')
response.write('4\n')
response.write('5\n')

response.end('');
  • 总结,(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,目前用不上