likes
comments
collection
share

静态服务器

作者站长头像
站长
· 阅读数 19

github地址

HTTP 模块

它是Node.js借助了libuv、httParser等一些C/C++ 语言的库,才得以实现,最终暴露给我们一些非常好用的API

配置Webstorm

一些有用的工具

esno

  • 是一个 CLI 命令(替代node),用于在包类型中无缝运行 TypeScript 和commonjsESM module

它由esbuild提供支持,因此速度非常快。

node-dev

  • 当文件更新时自动重启的node(服务器默认是24h运行除非ctrl + c 中断,重新运行程序)
  • 避免每次改完代码都要重新运行的麻烦
  • 不宜在生产环境使用

ts-node

  • 让node支持直接运行TypeScript代码
  • 不宜在生产环境使用

ts-node-dev( 推荐 )

  • 这个工具结合了上面两个工具
  • 可以用TypeScript开发Node.js程序,且会自动重启
  • 不宜在生产环境使用,但非常适合用来学习

安装ts-node-dev: yarn global add ts-node-dev

一些有用的工具2

WebStorm自动格式化

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

静态服务器

WebStorm自动写代码

  • Complete Current Statement:(自动补全剩余部分逻辑代码和格式化代码) 设为 Ctrl + Enter
  • Show Context Actions(自动声明变量,自动引入包等) 设为 Alt + Enter
  • 把冲突的键位改为其他快捷键
  • 当然你可以设为其他键位

一些有用的工具3

WebStorm Git配置

  • 把WebStorm的git路径设置为Cmder里的
  • 示例:D:\user\Software\Cmder\vendor\git-for-windows\bin\git.exe
  • 好处是统一管理统一配置

下图是我使用的 git bash 静态服务器

一些有用的工具4

curl

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

创建项目

步骤

  • yarn int -y
  • 新建index.ts
  • 使用命令行或者webstorm启动(ts-node-dev index.ts,在这之前你要安装tsyarn gloval add typescript,然后tsc -init 初始化出一个tsconfig.json)

静态服务器

这样ts文件就可以使用node运行了

  • 如果我们在ts文件中直接引入node的模块,会发现一个问题:它找不到node中的模块,我们需要安装一个依赖:yarn add --dev @types/node 安装node所有模块的声明文件

当我们安装完成之后就会发现多了很多Node模块的ts文件

静态服务器

这样我们就可以在webstorm中开发Node.js的typescript的应用了

  • 引入http模块(webstorm自动引入,快捷键 Alt + Enter)
  • 用http创建server(webstorm自动命名,快捷键 Alt + Enter)
  • 监听server的request事件(可以简写)
  • server.listen(8888)开始监听8888端口
  • 启动server的方式:ts-node-dev index.ts这样它就会一直监听本机的8888端口
  • 使用curl -v http://localhost:8888 发请求

import * as http from "http";

const server = http.createServer();

// 监听server的request,如果服务器被人请求了
server.on('request', () => {
    console.log('有人请求了')
});

// 监听端口
server.listen(8888);

静态服务器

静态服务器

但是,请求端在等服务端的响应,但是服务端什么都没响应,因此服务端在等新的请求和请求端都在等服务端的响应,就这样进入死循环了...

ctrl + c 断开请求端和响应端

import * as http from "http";

const server = http.createServer();

// 监听server的request,如果服务器被人请求了
server.on('request', (request,response) => {
    console.log('有人请求了')
    response.end('服务端相应内容')
});

// 监听端口
server.listen(8888);

这样请求端得到了服务端的响应内容 静态服务器

服务端也得到了三次请求 静态服务器

requst对象

server是个什么东西

http.Server类的实例

静态服务器

  • 所以server是http.Server类的实例

静态服务器

进入http.server

发现有我们经常使用的API

静态服务器

静态服务器

  • 因此server拥有几个事件和方法
  • 其中也就request事件和listen()方法目前能用上

继承net.Server类

  • 根据文档知道http.Server继承了net.Server

  • 因此server就拥有了几个事件和方法

  • 其中也就error事件和address()方法目前能用上

  • 这就是看文档的方法(看它有哪些属性、事件、方法)

能否根据请求的了路径不同,响应不同的内容呢?

我们得知道用户请求了什么路径

server.on('request', (request,response) => {
    console.log('有人请求了')
    response.end('服务端相应内容')
});

从名字上可以看出request是请求相关的信息,response是响应相关的信息,但是这样猜是没有根据的,凭什么说request有这些东西

因此我们得知道request是由谁构造出来的对象,console.log(request.constructor)

静态服务器

我们可以看出:request的构造者是IncomingMessage,我们知道了构造它的类是不是就知道它有哪些属性?

我们可以通过文档去查这个类,或者控制台打印出这个类,或者单击进入

静态服务器

为什么明明request下没有那么多属性或方法,我们在webstorm中,通过request. 却不提示它拥有的属性或方法呢?

因为ts并不知道它是什么类型的对象,我们得告诉ts,这个request是IncomingMessage对象

下面介绍第一个ts的语法: 加类型标注

server.on('request', (request:IncomingMessage,response) => {
 ...
});

这样在webstorm中通过request.就可以展示所有request的属性方法,就算不看文档也知道怎么使用了

(webstorm小技巧:request.httpVersion.log按下tab键就可以控制台打印)

这样我们就可以从request中获取到请求路径了

console.log(request.httpVersion);
console.log(request.url);

静态服务器

静态服务器

那么同样的道理,response 是什么呢? 通过console.log(response.constructor);把它的constructor打印出来

静态服务器

也就是说response的类型就是ServerResponse

同样的我们使用ts给response加类型标注

server.on('request', (request:IncomingMessage,response:ServerResponse) => {
   ...
});

当我们添加标注后,webstorm就智能的帮我们引入了ServerResponse模块,写代码太舒服了

通过response.就可以获得所有response的属性方法了

静态服务器

至此,我们就知道了request是由IncomingMessage类构造出来的,response是由ServerResponse类构造出来的

用Node.js获取请求内容

get请求

  • request.method 获取请求动词
  • request.url 获取请求路径(含查询参数)
  • request.header 获取请求头
  • get请求一般没消息体/请求体

post请求

  • curl-v -d "name=user" http://localhost:8888
  • request.on('data',fn) 获取消息体
  • request.on('end',fn) 拼接消息体

如果我们在请求的时候,加上-v参数,请求完成后我们会得到请求内容

curl -v http://localhost:8888/xxx

静态服务器

其中:

  1. Headers有三个部分: Host、User-Agent、Accept,大于号>表示请求
  2. 小于号<表示响应

服务器中获取到了请求的内容

server.on('request', (request:IncomingMessage,response:ServerResponse) => {
    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('服务端相应内容')
});

静态服务器

那么如果是一个post请求呢?

当curl 命令后加 -d 后就会自动的将get请求转成post请求

请求端: curl -v -d "name=LG" http://localhost:8888/xxx

静态服务器

服务端: 响应内容

静态服务器

但是我们拿不到post请求的请求体啊(name=LG怎么没有获取到?)

Node.js如何获取到POST请求的请求体 / 消息体?

我们需要监听request的data,怎么知道要监听request的data呢?

看下文档 v12,知道post的constructor是IncomingMessage,而IncomingMessage又继承自stream.readable,它是有data事件的,因此post上是有data事件的

静态服务器

静态服务器

那么这个data事件是什么意思呢?

当用户上传内容的时候,每上传一个字节或者一段内容就会触发data事件

假设用户要上传2M的内容,那么它是分几次上传?如果是一次,那么只要中间出了什么差池,那么2M的内容就全毁了

如果了解tcp协议就会知道: 每次上传的报文的大小是固定的,可能是几k的大小,这样就慢慢的上传。所以就会不停的触发data事件,因此我们要监听每一次的data事件,把每次data返回结果放到一个数组中

chunk的意思就是一小块数据的意思

那么什么时候才结束呢?因此我们要监听上传结束事件,文档中有说明

静态服务器

当上传结束的时候就要把array中的数据链接起来

request.on('end', () => {
    const body = Buffer.concat(array).toString();
    console.log('body');
    console.log(body)
    response.end('服务端相应内容')
})

请求端:

静态服务器

响应端:

静态服务器

这种上传方式,就算上传1G的内容也能拿到,因为服务器在监听一小段一小段的data放到数组中然后把数组连起来,只要服务器内存够,就可以处理1G的文件

这就是Node.js获取post请求中请求体的过程:

import * as http from "http";
import {IncomingMessage, ServerResponse} from "http";

const server = http.createServer();

// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    console.log(request.method);
    console.log(request.url);
    console.log(request.headers);
    let array:any = []
    request.on('data', (chunk) => {
        array.push(chunk);
    })
    request.on('end', () => {
        const body = Buffer.concat(array).toString();
        console.log('body');
        console.log(body)
        response.end('服务端相应内容')
    })
});

// 监听端口
server.listen(8888);

(request,response) 是啥

找类

Request

  • 拥有headers、methods、url等属性
  • 从stream.Readable类继承了 data/end/error事件
  • 为什么不能直接拿到post请求的请求体,而是要获取一段一段的buffer,再去拼接呢? 跟TCP有关

Response

  • 拥有getHeader/ setHeader / end / write等方法
  • 拥有statusCode属性,可读可写
  • 继承了Stream,目前用不上

response对象

修改状态码

目前,请求端发起请求后,response只能响应简单的'hi'

实际上我们还可以改很多东西,如:改掉200 / ok ,改为400

response.statusCode = 400;

静态服务器

当然我们也可以在浏览器中发起请求

import * as http from "http";
import {IncomingMessage, ServerResponse} from "http";

const server = http.createServer();

// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    console.log(request.method);
    console.log(request.url);
    console.log(request.headers);
    let array: any = []
    request.on('data', (chunk) => {
        array.push(chunk);
    })
    request.on('end', () => {
        const body = Buffer.concat(array).toString();
        console.log('body');
        console.log(body)
        response.statusCode = 400;

        response.end('hi')
    })
});

// 监听端口
server.listen(8888);

静态服务器

我们也可以把响应的code改为404,怎么才能像平时访问的404网页那样,"您访问的网页找不到了.."

那我们response.end('hi')的时候就不要给'hi'内容了,而是直接endresponse.end()

静态服务器

当浏览器发现,response只返回了404,没有返回任何内容,那么浏览器就会返回一个404的html网页

添加任意内容

我们可以再在response中加一些内容

response.setHeader('X-name', 'I am LG');

静态服务器

设置响应体

通过response.write('')往响应体中写内容

request.on('end', () => {
    const body = Buffer.concat(array).toString();
    console.log('body');
    console.log(body)
    response.statusCode = 400;
    response.setHeader('X-name', `I am LG`);
    response.write('响应体内容1\n');
    response.write('响应体内容2\n');
    response.write('响应体内容3\n');
    response.write('响应体内容4\n');
    response.end()
})

静态服务器

因此,整个响应的内容都可以使用Node.js去控制

那么响应体中只能响应字符串或者Buffer吗?可以响应图片吗?我们可以在response.write('')中响应一个二进制的图片

当然,响应头中要设置一下ContentType

request.on('end', () => {
    const body = Buffer.concat(array).toString();
    console.log('body');
    console.log(body)
    response.statusCode = 400;
    response.setHeader('X-name', `I am LG`);
    response.setHeader('Content-Type', `image/png`);
    
    response.write(ImageData);

    response.end()
})

这样用户访问首页,就可以得到一张图片了

完成目标1: 根据url返回不同的文件

如果访问的路径是/index.html那么就返回一个静态文件,一般放在static / public文件夹中(这个文件夹中的代码都是运行在浏览器中,而不是运行在Node.js中)

这里我们在根目录下新建public文件夹,在它下面新建一个index.html、style.css、main.js

如果访问的路径是/index.html就要读当前目录下的public/index.html

我们要借助Node.js中的path模块去处理路径拼接

文档链接

Node.js中的全局变量__dirname表示当前文件所在目录

静态服务器

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

const server = http.createServer();
const publicDir = p.resolve(__dirname,'public')
// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    const {method, url, headers} = request
    switch (url){
        case  '/index.html':
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir,'index.html'),(error,data)=>{
                if(error) throw error;
                response.end(data.toString())
            })
        break;
        case  '/style.css':
            fs.readFile(p.resolve(publicDir,'style.css'),(error,data)=>{
                if(error) throw error;
                response.end(data.toString())
            })
            break;
        case  '/main.js':
            fs.readFile(p.resolve(publicDir,'main.js'),(error,data)=>{
                if(error) throw error;
                response.end(data.toString())
            })
            break;
    }
});

// 监听端口
server.listen(8888);

我们可以发现一个问题,我们要访问的内容都被当做html展示出来了,因此我们要告诉浏览器它是css还是js

静态服务器

静态服务器

静态服务器

我们需要告诉指定内容的类型是什么response.setHeader('Content-Type','text/css;charset=utf-8')

这样浏览器才知道这是css响应

同样的响应的JS文件,也要设置一下

response.setHeader('Content-Type','text/javascript;charset=utf-8')

静态服务器

接着让index.html引用style.css和main.js

静态服务器

虽然即使我们服务器,在响应的时候不说明响应文件的类型,浏览器发现index.html中使用了link标签自动识别出文件为css文件,使用script标签的文件为js文件

静态服务器

但是为了让写法更加完整,最好还是在响应头中说明文件的类型

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

const server = http.createServer();
const publicDir = p.resolve(__dirname, 'public')
// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    const {method, url, headers} = request
    switch (url) {
        case  '/index.html':
            response.setHeader('Content-Type', 'text/html;charset=utf-8')
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir, 'index.html'), (error, data) => {
                if (error) throw error;
                response.end(data.toString())
            })
            break;
        case  '/style.css':
            response.setHeader('Content-Type', 'text/css;charset=utf-8')
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir, 'style.css'), (error, data) => {
                if (error) throw error;
                response.end(data.toString())
            })
            break;
        case  '/main.js':
            response.setHeader('Content-Type', 'text/javascript;charset=utf-8')
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir, 'main.js'), (error, data) => {
                if (error) throw error;
                response.end(data.toString())
            })
            break;
    }
});

// 监听端口
server.listen(8888);

完成目标2: 处理查询参数

当我们在请求html的时候有时候要加一个参数,如:http://localhost:8888/index.html?q=1

我们不妨打印一下这个url

静态服务器

可以发现url竟然包含了?q=1

这时候我们就要借助Node.js中的url模块来解决这个问题,但是由于之前的代码中从request中引入了url,和这里的url模块重命了,所以要重新命名一下

const {method, url, headers} = request

改为

const {method, url:path, headers} = request

查文档 url.parse

静态服务器

接下来,我们不妨看下结果url处理过的path会变成什么?

const object = url.parse(path as string)
console.log(object)

静态服务器

这样就把路径和查询参数单独摘出来了,我们就可以单独的去获取了!!

const {pathname,search} = url.parse(path as string)

这样查询字符串就不会之前代码中的switch case 中的逻辑了

这样我们就使用url.parse()获取到了基本路径和查询参数

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')
// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    const {method, url:path, headers} = request
    const {pathname,search} = url.parse(path as string)
    switch (pathname) {
        case  '/index.html':
            response.setHeader('Content-Type', 'text/html;charset=utf-8')
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir, 'index.html'), (error, data) => {
                if (error) throw error;
                response.end(data.toString())
            })
            break;
        case  '/style.css':
            response.setHeader('Content-Type', 'text/css;charset=utf-8')
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir, 'style.css'), (error, data) => {
                if (error) throw error;
                response.end(data.toString())
            })
            break;
        case  '/main.js':
            response.setHeader('Content-Type', 'text/javascript;charset=utf-8')
            // data是Buffer,要转成string
            fs.readFile(p.resolve(publicDir, 'main.js'), (error, data) => {
                if (error) throw error;
                response.end(data.toString())
            })
            break;
    }
});

// 监听端口
server.listen(8888);

完成目标3: 匹配任意文件

当前只能回去三个文件,如果当前在根目录下加一个叫jquery.js文件,然后在index.html中引入这个js文件

我们在浏览器中访问http://localhost:8888/index.html?q=1,我们会发现我们获取不到jquery.js

静态服务器

为什么呢?因为我们在响应中没有处理,那难道每加一个文件,都要作响应的处理吗?

我们希望如果引入了别的文件,我们不想改任何内容,会自动的匹配到哪个文件,我们该怎么办呢

我们观察一下之前的代码,其实很多内容都是一样

静态服务器

我们只需要从请求的路径中获得到文件名,然后用publicDir拼接文件名即可得到完整的请求路径

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')
// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    const {method, url:path, headers} = request
    const {pathname,search} = url.parse(path as string)
    // response.setHeader('Content-Type', 'text/html;charset=utf-8')
    // data是Buffer,要转成string
    const fileName = (pathname as string ).substr(1)
    fs.readFile(p.resolve(publicDir, fileName), (error, data) => {
        if (error){
            response.statusCode = 404
            response.end()
        }else{
            response.end(data.toString())
        }
    })


});

// 监听端口
server.listen(8888);

我们发现所有文件都可以请求到了

静态服务器

即使我们在public目录下新创建xxx的目录,再创建一个aa.html,在浏览器中也是可以访问到的

静态服务器

静态服务器

如果访问的路径/文件不存在

静态服务器

到此,就实现了一个静态服务器了,public中的文件只要访问的路径存在,就都可以访问到了

完成目标4:处理不存在的文件 -返回404页面

如果访问的路径不存在,我们打印error

静态服务器

接下来我们要处理400的错误和内部服务器的错误(如:权限问题),根据error.errno来判断错误类型

if (error.errno === -4058) {
    response.statusCode = 404
    console.log(p.resolve(publicDir, '404.html'))
    fs.readFile(p.resolve(publicDir, '404.html'), (err, data) => {
        response.end(data)
    })
}else {
    response.statusCode = 500
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.end('服务器繁忙,请稍后再试')
}

如果访问的路径不存在,就去读404.html

注意: 如果index中插入的图片请求不到,请在图片地址前加上/,请在图片地址前加上/,请在图片地址前加上/!!!!!!!!!!!!!!!

静态服务器

对比下路径加/和不加/图片请求图片路径的区别:

静态服务器

静态服务器

静态服务器

当我们尝试访问首页的时候,会显示服务器繁忙?

静态服务器

因为此时,filename是空的,pathname是/

if(fileName === ''){ fileName = 'index.html' }

如果访问的路径是纯目录,那么也会报错,针对这个错误类型再加一个判断即可

if(error.errno === -4068){
    response.statusCode = 403
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.end('无权查看纯目录了路径')
}

静态服务器

至此,处理不存在的文件,返回404页面的功能就全部实现了

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')
// 监听server的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    const {method, url: path, headers} = request
    const {pathname, search} = url.parse(path as string)
    // response.setHeader('Content-Type', 'text/html;charset=utf-8')
    // data是Buffer,要转成string
    let fileName = (pathname as string).substr(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
                console.log(p.resolve(publicDir, '404.html'))
                fs.readFile(p.resolve(publicDir, '404.html'), (err, data) => {
                    response.end(data)
                })
            }else if(error.errno === -4068){
                response.statusCode = 403
                response.setHeader('Content-Type', 'text/html;charset=utf-8')
                response.end('无权查看纯目录了路径')
            } else {
                response.statusCode = 500
                response.setHeader('Content-Type', 'text/html;charset=utf-8')
                response.end('服务器繁忙,请稍后再试')
            }
        } else {
            response.end(data)
        }
    })


});

// 监听端口
server.listen(8888);

完成目标5: 处理非GET请求

用的时候用户发起的并不是get请求,如:页面中有form表单

静态服务器

静态服务器

当单击post时候会发送post请求

静态服务器

我们应该阻止用户发送post请求,并提示用户不能使用post而不是返回404页面

我们应该对method进行过滤,静态服务器是不能接收post请求

if(method !== 'GET'){
    // 表明服务器禁止了使用当前HTTP 方法的请求
    response.statusCode = 405;
    response.end();
    return
}

静态服务器

至此,就完成了处理非GET请求的功能

完成目标6: 添加缓存选项

添加缓存选项,减少第二次请求相同路径的时间

我们可以借助Cache-Concol

let cacheAge = 3600 * 24 *365;

response.setHeader('Cache-Control',`public,max-age=${cacheAge}`)

可以看出除了首页不能缓存外,其他文件都缓存了,也就是第二次重复请求相同地址时,有些文件就直接从内存的缓存中读取了,缓存时间为一年,在这段时间内,不会再访问服务器,每次请求时间都是0秒

静态服务器

如果想更新缓存,就更改文件名

全部代码

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的request,如果服务器被人请求了
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
    const {method, url: path, headers} = request
    const {pathname, search} = url.parse(path as string)
    if(method !== 'GET'){
        // 405表明服务器禁止了使用当前HTTP 方法的请求
        response.statusCode = 405;
        response.end();
        return
    }
    // response.setHeader('Content-Type', 'text/html;charset=utf-8')
    let fileName = (pathname as string).substr(1)
    if(fileName === ''){
        fileName = 'index.html'
    }
    fs.readFile(p.resolve(publicDir, fileName), (error, data) => {
        if (error) {
            console.log(error)
            if (error.errno === -4058) {
                // 404表示网页或文件未找到
                response.statusCode = 404
                console.log(p.resolve(publicDir, '404.html'))
                fs.readFile(p.resolve(publicDir, '404.html'), (err, data) => {
                    response.end(data)
                })
            // 访问的的是纯目录路径,403表示服务器端有能力处理该请求,但是拒绝授权访问
            }else if(error.errno === -4068){
                response.statusCode = 403
                response.setHeader('Content-Type', 'text/html;charset=utf-8')
                response.end('无权查看纯目录了路径')
            } else {
                response.statusCode = 500
                response.setHeader('Content-Type', 'text/html;charset=utf-8')
                response.end('服务器繁忙,请稍后再试')
            }
        } else {
            // 添加缓存
            response.setHeader('Cache-Control',`public,max-age=${cacheAge}`)
            // 返回文件内容
            response.end(data)
        }
    })


});

// 监听端口
server.listen(8888);

对比业界优秀案例

对比业界优秀案例,发现他们提供了哪些功能,哪些功能我们是可以做的,完善我们自己的静态服务器

http-server

node-static

免费获得正版webstorm使用的的权限

不要浪费你的代码,持续维护三个月,可以换webStorm一年的使用权限

发布到npm

申请条件

  • 你是开源项目的核心贡献者
  • 你的项目是开源的(如MIT许可证)
  • 你的项目是不盈利的
  • 你的项目至少活跃了3个月(每个月至少提交一次代码)
  • 你定义发布更新的版本
  • 满足条件就点击申请按钮

填写材料

  • 邮箱地址一定不要填错
  • No. of required licenses 处填1
  • 项目描述用Google翻译
  • 正版JetBrains全家桶唾手可得,价值$649/ 年