最近用node搞了一个静态服务器,也就是跑一条server,用于提供静态资源访问的功能,如图片、CSS、JS等。
功能主要涉及如下几个点:
一、支持对CSS、JS、html等资源访问
由于所有的请求都由node服务承担,需要对过来的请求做路由逻辑,以获取对应的资源。那么怎么区分过来的资源类型?然后走不同的路由逻辑获取资源?
我们请求的资源是有后缀名,比如http://www.baidu.com/source.js的.js,利用mime(描述消息内容类型的因特网标准)来判断资源的类型,从而指定响应报文的content-type值,让浏览器对获取到的数据,按照特定格式进行解析,从而得到我们的js代码。
二、支持css、js、图片静态资源缓存。
这里主要用到if-none-match与etag、if-modified-since与last-modified这两对字段。通过进行比较,控制http返回码,如304等,让浏览器决定是否复用之前下载的副本。
if-modified-since与last-modified主要存储资源的修改时间,一般精确到秒,如果修改时间相同,那么可以使用副本,返回304。
last-modified是服务器生成,if-modified-since是浏览器请求携带
if-none-match与etag主要解决场景是:一个资源可能修改频繁,但文件内容不一定会变化。所以if-modified-since与last-modified的策略可能不起作用。
etag的值并没有强制要求格式,可以是一个hash,比如文件内容的md5值,通过比对if-none-match与etag是否匹配,来决定让浏览器是否使用资源副本。但是读取文件内容,产生md5值,会有性能开销。
etag是服务器生成,if-none-match则是浏览器携带。
这里不适用md5计算内容,是因为文件读取有开销,改成读取文件尺寸(修改内容,但是文件大小不变,概率较小)
判断资源是否还新鲜的方法:
三、支持css、js、html的gzip压缩
在要传输给客户端的代码文件中,会出现一些重复性字符串,如果可以通过特定算法,对其进行压缩,然后传输到客户端再解压还原。节省网络传输过程中的带宽。从而达到提高传输速度的目的。
要实现这样的目的,服务器要能进行压缩,客户端要能进行解压,然后双方必须使用同的算法规则进行解压和压缩。这样的算法有很多,gizp是其中之一,而node的zilb库支持这样的算法使用。
实现过程:
然后在network面板对比下载资源的前后尺寸大小,便可体会gzip压缩的作用。
这里不对图片做gzip压缩,因为压缩、解压前后,图片可能因为压缩算法的问题,导致内容变了。这里简单的应用http缓存策略来优化请求即可。
二、支持video的端点传输
视频本身一开始是不会下载的,需要你点击播放后,逐段二进制数据下载到浏览器,再做二次渲染。
中间会涉及到range请求,详见http规范,核心点在于每段请求都会有一个返回,逐片请求视频的数据,放到浏览器播放。通过206返回码逐渐加载资源。
计算range范围的方法:
详细代码在github上:https://github.com/87244099/staticServer/blob/master/app.jsgithub.com