express中间件的实现

1.自定义静态文件目录

/**
*自定义定义静态文件目录中间件
*/
var express=require('express');
var path=require('path');
var fs=require('fs');
var bodyParser=require('body-parser');
var app=express();
app.set('views',path.join(__dirname,'views'));
app.set('view engine','ejs');

//普安短是否是结束字符串
var endWith=function(str,endStr){  
            if(endStr==null||endStr==""||str.length==0||endStr.length>str.length)  
              return false;  
            if(str.substring(str.length-endStr.length)==endStr)  
              return true;  
            else  
              return false;  
            return true;  
        }  
function serverStatic(root){
    return function(req,res,next){
        //console.log(req.baseUrl); /public
        //console.log(req.originalUrl); ///public/index.css
        var file=req.originalUrl.slice(req.baseUrl.length+1);
        file=path.resolve(root,file);
        //判断file是否查出public范围
        if(file.indexOf('Middleware')==-1){
                next();
                return;
        }
        //判断是文件还是目录
        fs.stat(file, function(err,stats){
            if(err){
                 next();
            } else if(stats.isFile()){//是文件,直接响应
                    if(endWith(file,'.css')){
                        res.setHeader("Content-Type", "text/css");
                    } else if(endWith(file,'.html')){
                        res.setHeader("Content-Type", "text/html");
                    } 
                    
                    var stream=fs.createReadStream(file);
                    stream.pipe(res);
            }  else if(stats.isDirectory()){//是目录
                    if(file[file.length-1]!=='/'){
                        file=file+'/';
                    }
                    fs.exists(file+'index.html', function(exists){ //添加默认路径
                        if(exists){
                            res.setHeader("Content-Type", "text/html");
                            var stream=fs.createReadStream(file+"index.html");
                            stream.pipe(res);
                        } else {
                            next();
                        }
                    }); 
            }
        });
    }
}

//定义数据解析器
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

//定义静态文件目录
//app.use(express.static(path.join(__dirname,'public')));
//自定义静态文件目录
app.use('/public',serverStatic(path.join(__dirname,'public')));

app.get('/',function(req,res){
    res.render('index',{title:'首页'});
});

app.listen(3000,function(req,res){
    console.log('app is runing at port 3000');
});

2.自定义文件存储session会话信息

/*
--path   session存储路径默认 ./sessions
--ttl   session 过期时间 默认3600

--retries   默认从session文件中读取的次数.默认 5
--factor    重用的指数因子默认为 1
--minTimeout    第一次尝试间隔时间,默认 50
--maxTimeout 最大两次重试的时间间隔,默认 100

--reapIntervalObject [OUT] Contains intervalObject if reap was scheduled
--reapInterval      Interval to clear expired sessions in seconds or -1 if do not need. Defaults to 1 hour
--reapAsync         use distinct worker process for removing stale sessions. Defaults to false
--reapSyncFallback  reap stale sessions synchronously if can not do it asynchronously. Default to false

--logFn             日志信息. 默认存储在console.log
--fallbackSessionFn 返回 fallback session object 当所有的尝试失败了 无默认值
--encrypt 存储和读取加密
*/
//完全参考session-file-store
var helper=require('./file-helper');
var fs = require('fs-extra');
module.exports=function(session){//获得session
    //此处可以看出闭包的威力
    var Store=session.Store;//获得session的Store一会需要继承它
    //定义一个对象,继承自session的Store
    function FileStore(options){
        var self=this;
        Store.call(this,options);//因为参数不固定,所以用了call
        self.options = helper.defaults(options);//获得默认参数
        fs.mkdirsSync(self.options.path);//创建目录
    }
    /**
   *集成Store对象
   prototype.__proto__指向prototype类的原型。
   这里不是单纯的覆盖原型,而是更在更高一层覆盖。
   FileStore.prototype= Store.prototype;这样就直接覆盖了
   */
  FileStore.prototype.__proto__ = Store.prototype;

  /**
   * 根据sessionId 获得Session
   *
   * @param  {String}   sessionId
   * @param  {Function} callback
   *
   * @api public
   */
  FileStore.prototype.get = function (sessionId, callback) {
    helper.get(sessionId, this.options, callback);
  };

  /**
   *设置Session
   *
   * @param {String}   sessionId
   * @param {Object}   session
   * @param {Function} callback (optional)
   *
   * @api public
   */
  FileStore.prototype.set = function (sessionId, session, callback) {
    helper.set(sessionId, session, this.options, callback);
  };

  /**
   * 跟新session
   *
   * @param {string} sessionId
   * @param {object} session
   * @param {function} callback
   *
   * @api public
   */

  FileStore.prototype.touch = function (sessionId, session, callback) {
    // will update last access time
    helper.set(sessionId, session, this.options, callback);
  };

  /**
   * 删除Session
   *
   * @param  {String}   sessionId   Files are serialized to disk by their
   *                                sessionId
   * @param  {Function} callback
   *
   * @api public
   */
  FileStore.prototype.destroy = function (sessionId, callback) {
    helper.destroy(sessionId, this.options, callback);
  };

  /**
   * 获得Session的长度
   *
   * @param  {Function} callback
   *
   * @api public
   */
  FileStore.prototype.length = function (callback) {
    helper.length(this.options, callback);
  };

  /**
   * 清空session
   *
   * @param  {Function} callback
   *
   * @api public
   */
  FileStore.prototype.clear = function (callback) {
    helper.clear(this.options, callback);
  };

  /**
   * 获得所有的session
   *
   * @param  {Function} callback
   *
   * @api public
   */
  FileStore.prototype.list = function (callback) {
    helper.list(this.options, callback);
  };

  /**
   * 判断session是否过期
   *
   * @param  {String}   sessionId
   * @param  {Function} callback
   *
   * @api public
   */
  FileStore.prototype.expired = function (sessionId, callback) {
    helper.expired(sessionId, this.options, callback);
  };
  return FileStore;
}

你可能感兴趣的:(express中间件的实现)