当你输入一个url时,这个url可能对应服务器上的一个资源(文件)也可能对应一个目录。 So服务器会对这个url进行分析,针对不同的情况做不同的事。 如果这个url对应的是一个文件,那么服务器就会返回这个文件。 如果这个url对应的是一个文件夹,那么服务器会返回这个文件夹下包含的所有子文件/子文件夹的列表。 以上,就是一个静态服务器所主要干的事。
但真实的情况不会像这么简单, 我们所拿到的url可能是错误的,它所对应的文件或则文件夹或许根本不存在, 又或则有些文件和文件夹是被系统保护起来的是隐藏的,我们并不想让客户端知道。 因此,我们就要针对这些特殊情况进行一些不同的返回和提示。
再者,当我们真正返回一个文件前,我们需要和客户端进行一些协商。 我们需要知道客户端能够接受的语言类型、编码方式等等以便针对不同浏览器进行不同的返回处理。 我们需要告诉客户端一些关于返回文件的额外信息,以便客户端能更好的接收数据: 文件是否需要缓存,该怎样缓存? 文件是否进行了压缩处理,该以怎样的方式解压? 等等...
至此,我们已经初步了解了一个静态服务器所主要做的几乎所有事情, let's go!
实现
项目目录
配置文件
要启动一个服务器,我们需要知道这个服务器的启动时的端口号和静态服务器的工作目录
整体框架
注意
事件函数中的this默认指向绑定的对象(这里是小server),这里修改成了Server这个大对象,以便调用在回调函数中调用Server下的方法。
request请求处理
获取url的 pathname ,和 服务器本地的工作根目录地址 进行拼接,返回一个 filename 利用filename和 stat方法 检测是文件还是文件夹
是文件夹, 利用 readdir方法 返回该文件夹下的列表,将列表包装成一个对象组成的数组 然后结合handlebar将数组数据编译到模板中,最后返回这个模板给客户端
是文件, 将req、res、statObj、filepath传递给 sendFile ,接下来交由sendFile处理
[tip] 我们将 request 方法 async 化,这样我们就能像写同步代码一样写异步
方法
sendFile
涉及缓存、编码、分段传输等功能
handleCache
缓存处理时要注意的是,缓存分为强制缓存和对比缓存,且强制缓存的优先级是高于相对缓存的。 也就是说,当强制缓存生效的时候并不会走相对缓存,不会像服务器发起请求。 但一旦强制缓存失效,就会走相对缓存,如果 文件标识 没有改变,则相对缓存生效, 客户端仍然会去缓存数据拿取数据,所以强制缓存和相对缓存并不冲突。 强制缓存和相对缓存一起使用时,能在减少服务器的压力的同事又保持请求数据的及时更新。
另外需要注意的是,如果同时设置了两种相对缓存的文件标识,必须要两种都没有改变时,缓存才生效。
let lastModified = statObj.ctime.toGMTString(); //此时间格式可配置
res.setHeader('Etag',etag);
res.setHeader('Last-Modified',lastModified);
if(isNoneMatch && isNoneMatch != etag) return false; //若是第一次请求已经返回false
if(ifModifiedSince && ifModifiedSince != lastModified) return false;
if(isNoneMatch || ifModifiedSince){
// 说明设置了isNoneMatch或则isModifiedSince且文件没有改变
res.writeHead(304);
res.end();
return true;
}esle{
return false;
}
}
getEncoding
从请求头中拿取到浏览器能接收的编码类型,利用正则匹配匹配出最前面那个, 创建出对应的zlib实例返回给sendFile方法,以便在返回文件时进行编码。
getStream
分段传输,主要利用的是请求头中的 req.headers['range']
来确认要接收的文件是从哪里开始到哪里结束,然而真正拿到这部分数据是通过 fs.createReadStream
来读取到的。
包装成命令行工具
我们可以像在命令行中输入 npm start
启动一个dev-server
一样自定义一个启动命令来启动我们的静态服务器。
大体实现的思路是: 在 packge.json 中的 bin 属性下配置一个启动命令和这个执行这个命令的文件的路径。 然后我们需要准备一个批处理文件,在文件中引入我们的静态服务器文件,让我们的服务器跑起来 然后将这个文件 node link 即可。
总结
以上所述是小编给大家介绍的Node.js静态服务器的实现方法。编程之家 jb51.cc 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持。
原文链接:https://www.f2er.com/nodejs/33484.html