欢迎大家指导与讨论 : )

  一、什么是静态资源

  静态资源就是放在服务器中的特定的文件。比较常见的有.css,.png, .js的这一些后缀的文件。下图中的这个html页面便要获取到logo.png和asd.css这两个在服务器中的文件。而服务器呢,也要根据这些各种各样资源的请求,返回对应的MIME类型和对应的资源。分享一个查询MIMEType的地址 http://www.freeformatter.com/mime-types-list.html#mime-types-list  本文最后有实现代码~

  二、为什么需要静态资源管理服务

  那为什么我们需要资源管理服务呢?比如说上图的这个html文件,当我们进入到http://127.0.0.1/index.html(这里举个例子),这个文件不是会自己申请logo.png和asd.css资源了吗?我们还需要做其他的东西吗?对的。这个文件(html)确实会发出这两个资源的请求。如下图。但是各位注意哦~这两个请求资源的pathname我们没有在服务器中进行处理,因此html文件是无法获取到嵌套在html里面的这几个文件的~比如说,一位妈妈第一次带着她的两个小孩去图书馆,妈妈呢一早就有图书馆的通行证了(在服务器中对"妈妈"这个请求资源授予处理)~所以呢,管理员可以让妈妈同行。但是那两位小朋友呢,由于还没有办卡(服务器没有对该资源请求进行处理),所以呢那两位小朋友不让进去图书馆。因此,我们需要在服务器中额外增加一个静态资源管理服务,针对这些额外的资源请求来进行对应的处理(相当于在那个图书馆建一个办卡区,图书馆管理员: "hey! 你们两个! 先过去那边办卡就可以进去了!")。

  三、怎么构建静态资源管理服务

  解决方案是:根据不同请求的资源的后缀,返回不同的mime-type,并使用不同的资源的路径来返回对应资源。简单来说,就是根据某位同学的姓名,去到对应的宿舍,然后就能找到他/她。

  三 . 1 MIME-Type

  MIME-Type就是某个不同后缀的文件,会有其对应的MIME类型(比如说 .苹果是水果类, .生菜是蔬菜类)。我们返回资源的同时还要一起返回它对应的MIME类型,以便浏览器能够根据这个MIME资源,正确地解析出我们所返回的资源。(分享:上面有个需要FQ才能上,但是比较全的MIME查询网站)。通常呢,我们把这些后缀名称和它所对应MIME类型做出一个.json文件,以便服务器能够查询。

  三 . 2 构建静态资源管理服务

  让我们先理一下具体的操作步骤吧~

  1. 服务器接受到"/index"的请求  2. 服务器返回一个"index.html"页面  3. "index.html"发出"logo.png"和"asd.css"的资源请求  4. 服务器进入静态资源管理服务模块  5. 管理模块获取这两个资源请求的pathname和后缀名extname  6. 定义资源的具体路径(__dirname + '/xxx' + pathname或者__dirname + pathname这个根据不同架构会用略小的差别)  7. 根据mime_type.json获取这两个资源对应的MIME类型  8. 根据资源的路径,查询服务器上是不是存在这个资源  9. 不存在则返回404  10. 存在则读取资源并返回给客户端(到这步我们已经成功构建了静态资源的管理服务了)  11. 缓存部分 请继续往下看吧O(∩_∩)O)

  四、浏览器中的静态资源缓存

  当我们还没有设置资源缓存的时候(比如说刚刚的llogo.png和asd.css),即使浏览器已经通过服务器下载到了这两个资源,但是每当我们刷新浏览器的时候,浏览器还会继续从服务器中拉取所需要的资源,并增加了服务器的压力。我们需要做的是:当浏览器再次刷新时,让它从本地的缓存库(浏览器第一次访问服务器,并在服务器中所下载好的资源)中获取对应的资源,而不是又从服务器中重新下载一遍。

  四 . 1 资源的属性与If-Modified-Since

  每个浏览器所下载好的文件,浏览器都会知道这个文件(资源)的属性,包括这个文件创建时间、这个文件最后修改的时间(If-Modified-Since)等等一些信息。当浏览器的本地缓存中存在(比如是asd.css文件),但是不知道它还有木有效的时候,浏览器会发出一个条件get请求,而If-Modified-Since就包含在它的请求头中。我们所需要做的是进行判断:如果服务端文件在这个时间后发生过更改,则服务端发送文件给客户端,如果没有更改过,则返回304,不发送文件给客户端,而是让浏览器使用缓存中的同名资源。

  四 . 2 Expires和Cache-Control

  服务端在响应的时候带上expires头,浏览器会判断expires头,直到指定的日期过期,才会发起新的请求。

  、整体代码

/*static_module.js*/
var fs = require('fs');
var sys = require('util');
var http = require('http');
var url = require('url');
var path = require('path'); var BASE_DIR = __dirname;
var CONF = BASE_DIR + '/conf/';
var STATIC = BASE_DIR ;
var mimeConf = getUrlConf();
var CACHE_TIME = 60*60*24*365; exports.getStaticFile = function(pathname, res, req){
var extname = path.extname(pathname);
extname = extname ? extname.slice(1) : '';
var realPath = STATIC + pathname;
var mimeType = mimeConf[extname] ? mimeConf[extname] : 'text/plain';
console.log(extname); fs.exists(realPath, function(exists){
if(!exists){
console.log(realPath + " is not found.")
res.writeHead(404, {'Content-Type':'text/plain'});
res.write('Sorry, Not Found This Source.');
res.end();
}else{
var fileInfo = fs.statSync(realPath);
var lastModified = fileInfo.mtime.toUTCString(); if(mimeConf[extname]){
var date = new Date();
date.setTime(date.getTime() + CACHE_TIME * 1000);
res.setHeader("Expires", date.toUTCString());
res.setHeader("Cache-Control", "max-age=" + CACHE_TIME);
res.setHeader("Last-Modified", lastModified);
}
if(req.headers['if-modified-since'] && lastModified == req.headers['if-modified-since'] ){
res.writeHead(304, "Not Modified");
res.end();
}else{ fs.readFile(realPath, "binary", function(err, file){
if(err){
res.writeHead(500, {'Content-Type': 'text/plain'});
res.end(err);
}else{
res.writeHead(200, {'Content-Type': mimeType});
res.write(file, "binary");
res.end();
}
})
}
}
}) } function getUrlConf(){
var routerMsg = {};
try{
var str = fs.readFileSync(CONF + 'mime_type.json', 'utf8');
routerMsg = JSON.parse(str);
}catch(e){
sys.debug("JSON parse fails")
}
return routerMsg;
}

  参考资料

  《NodeJS开发实战详解》P96

NodeJS中的静态资源管理服务的更多相关文章

  1. gin中提供静态文件服务

    package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { // 静 ...

  2. Vue中的静态资源管理(src下的assets和static文件夹的区别)

    ### 你可能注意到了我们的静态资源共有两个目录src/assets和static/,你们它们之间有怎样的区别呢? 资源打包 为了回答这个问题,我们需要了解webpack是如何处理静态资源的. 在所有 ...

  3. Vue-cli中的静态资源管理(src/assets和static/的区别)

    资源打包 为了回答这个问题,我们需要了解webpack是如何处理静态资源的.在所有的*.vue文件中你所有的templates 和CSS 都被vue-html-loader 和css-loader 查 ...

  4. ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理

    对于一个应用来说界面的重要性无言而喻,而Web应用的界面是使用Html+Css以及Javascript实现的,ASP.NET MVC是一个用来构建Web应用的框架,它的界面也是Html实现的,对于一些 ...

  5. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理

    ASP.NET没有魔法——ASP.NET MVC Razor与View渲染   对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的 ...

  6. nodejs之获取客户端真实的ip地址+动态页面中引用静态路径下的文件及图片等内容

    1.nodejs获取客户端真实的IP地址: 在一般的管理网站中,尝尝会需要将用户的一些操作记录下来,并记住是哪个用户进行操作的,这时需要用户的ip地址,但是往往当这些应用部署在服务器上后,都使用了ng ...

  7. nodejs静态web服务

    项目准备 Web 服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等 Web 客户端提供文档,也可以放置网站文件,让全世界浏览:可以放置数据文件,让全世界下载.目前最主流的 ...

  8. nodejs anywhere 搭建本地静态文件服务

    一.背景 工作中有时候往往会遇到下述场景:例如需要将新打好的安装包等文件临时性的给到同事,可能还需要给到多个同事.这时,我们往往有如下几种方案: 1,一般都会有公司内部的文件系统,上传文件后将对应的地 ...

  9. nodejs 静态资源服务与接口代理跨域

    首先需要 npm install express 和 npm install request 代码如下: const express = require('express'); const path ...

随机推荐

  1. iOS 杂笔-22(万年一遇~一张图片对代理的理解)

    iOS 杂笔-22(万年一遇~一张图片对代理的理解) 建议:本博客需要对代理有一定了解方可阅读(反正我也管不到) 图片 在图片之外设置协议(没有这东西这篇博客也就是夭折了) 下面我对图片中出现的形形色 ...

  2. 浅析Dagger2的使用

    什么是Dagger2 Dagger是为Android和Java平台提供的一个完全静态的,在编译时进行依赖注入的框架,原来是由Square公司维护,现在由Google维护. 我们知道Dagger是一个依 ...

  3. 转载文章----C#基础概念

    转载地址:http://www.cnblogs.com/zhouzhou-aspnet/articles/2591596.html 1.值类型和引用类型 1.1堆和栈 简单的说值类型存放在堆栈上面,引 ...

  4. git之三

    1.status命令与diff命令 前面我们已经成功地添加并提交了一个readme.txt文件,修改readme.txt如下: echo "Git is a distributed vers ...

  5. ios app响应background,foreground 事件实现

    1 通过AppDelegate 实现 App进入后台事件方法 - (void)applicationDidEnterBackground:(UIApplication *)application AP ...

  6. SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

    前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...

  7. 烂泥:Linux源码包制作RPM包之Apache

    本文由秀依林枫提供友情赞助,首发于烂泥行天下 公司服务器比较多,需要把apache源码包制作成rpm包,然后放到公司内网yum源上进行下载安装.apache的rpm包安装方式比源码安装方式比较快,这能 ...

  8. centos---无线上网的电脑所安装的虚拟机网络设置

    1.共享设置 找到本地的无线网卡,右键---属性---共享,设置如下 2.修改VMware Network Adapter VMnet1 选中VMware Network Adapter VMnet1 ...

  9. Windows Azure虚拟机和云服务实例计费方式更新

    在之前的Windows Azure计费账单中,A0,A1,A2,A3,A4系列的虚拟机(云服务实例)都是以A1为基准计费单位的,即: 虚拟机大小 计费单位(小时) A0 A1*0.25 A1 A1*1 ...

  10. C#笔记---动态类(Dynamic)应用

    背景: 在Coding中有时候会遇到一些需要解析的数据,可是数据的字段数量和名称未统一,我们没法定义实体类来对应.那么我们就会想到通过C#的dynamic动态类来实现,如果大家注意的话一些ORM框架里 ...