Node.js HTML5 样板服务器配置集成

标签 node.js express html5boilerplate

我正在设置一个将使用 Node.js 和 Express 构建的新项目的结构。我正在使用 HTML5 Boilerplate以获得最佳起点。它自带多种类型服务器的配置文件:Apache、Nginx、Node.js等。下面是Node.js server configuration file由 HTML5 Boilerplate 团队提供:

/* h5bp server-configs project
 *
 * maintainer: @xonecas
 * contributors: @niftylettuce
 *
 * NOTES:
 * compression: use the compress middleware provided by connect 2.x to enable gzip/deflate compression
 *                          http://www.senchalabs.org/connect/compress.html
 *
 * concatenation: use on of the following middlewares to enable automatic concatenation of static assets
 *                              - https://github.com/mape/connect-assetmanager
 *                              - https://github.com/TrevorBurnham/connect-assets
 */
var h5bp    = module.exports,
   _http    = require('http'),
   _parse   = require('url').parse;

// send the IE=Edge and chrome=1 headers for IE browsers
// on html/htm requests.
h5bp.ieEdgeChromeFrameHeader = function () {
   return function (req, res, next) {
      var url = req.url,
         ua = req.headers['user-agent'];

      if (ua && ua.indexOf('MSIE') > -1 && /html?($|\?|#)/.test(url)) {
         res.setHeader('X-UA-Compatible', 'IE=Edge,chrome=1');
      }
      next();
   };
};

// block access to hidden files and directories.
h5bp.protectDotfiles = function () {
   return function (req, res, next) {
      var error;
      if (/(^|\/)\./.test(req.url)) {
         error = new Error(_http.STATUS_CODES[405]); // 405, not allowed
         error.status = 405;
      }
      next(error);
   };
};

// block access to backup and source files
h5bp.blockBackupFiles = function () {
   return function (req, res, next) {
      var error;
      if (/\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~/.test(req.url)) {
         error = new Error(_http.STATUS_CODES[405]); // 405, not allowed
         error.status = 405;
      }
      next(error);
   };
};

// Do we want to advertise what kind of server we're running?
h5bp.removePoweredBy = function () {
   return function (req, res, next) {
      res.removeHeader('X-Powered-By');
      next();
   };
};

// Enable CORS cross domain rules, more info at http://enble-cors.org/
h5bp.crossDomainRules = function () {
   return function (req, res, next) {
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With');
      next();
   };
};

// Suppress or force 'www' in the urls
// @param suppress = boolean
h5bp.suppressWww = function (suppress) {
   return function (req, res, next) {
      var url = req.url;
      if (suppress && /^www\./.test(url)) {
         res.statusCode = 302;
         res.setHeader('Location', url.replace(/^www\./,''));
      }
      if (!suppress && !/^www\./.test(url)) {
         res.statusCode = 302;
         res.setHeader('Location', "www."+url);
      }
      next();
   };
};

// Far expire headers
// use this when not using connect.static for your own expires/etag control
h5bp.expireHeaders = function (maxAge) {
   return function (req, res, next) {
      res.setHeader('Cache-Control', 'public, max-age='+ (maxAge));
      next();
   };
};

// Etag removal
// only use this is you are setting far expires for your files
// ** WARNING ** connect.static overrides this.
h5bp.removeEtag = function () {
   return function (req, res, next) {
      res.removeHeader('Last-Modified');
      res.removeHeader('ETag');
      next();
   };
};

// set proper content type
// @param mime = reference to the mime module (https://github.com/bentomas/node-mime)
h5bp.setContentType = function (mime) {
   return function (req, res, next) {
      // I'm handling the dependency by having it passed as an argument
      // we depend on the mime module to determine proper content types
      // connect also has the same dependency for the static provider
      // ** @TODO ** maybe connect/express expose this module somehow?
      var path = _parse(req.url).pathname,
         type  = mime.lookup(path);
      res.setHeader('Content-Type', type);
      next();
   };
};

// return a express/connect server with the default middlewares.
// @param serverConstructor = express/connect server instance
// @param options = {
//    root: 'path/to/public/files',
//    maxAge: integer, time in miliseconds ex: 1000 * 60 * 60 * 24 * 30 = 30 days,
//    mime: reference to the mime module ex: require('mime')
// }
// Depends:
//    express or connect server
//    mime module [optional]

h5bp.server = function (serverConstructor, options) {
   var server = serverConstructor.createServer(),
       stack = [
         this.suppressWww(true),
         this.protectDotfiles(),
         this.blockBackupFiles(),
         this.crossDomainRules(),
         this.ieEdgeChromeFrameHeader()
      //,this.expireHeaders(options.maxAge),
      // this.removeEtag(),
      // this.setContentType(require('mime'))
       ];
   // express/connect
   if (server.use) {
      stack.unshift(serverConstructor.logger('dev'));
      stack.push(
         //serverConstructor.compress(), // express doesn't seem to expose this middleware
         serverConstructor['static'](options.root, { maxAge: options.maxAge }), // static is a reserved
         serverConstructor.favicon(options.root, { maxAge: options.maxAge }),
         serverConstructor.errorHandler({
            stack: true,
            message: true,
            dump: true
         })
      );
      for (var i = 0, len = stack.length; i < len; ++i) server.use(stack[i]);
   } else {
      server.on('request', function (req, res) {
         var newStack = stack,
             func;
         (function next (err) {
            if (err) {
               throw err;
               return;
            } else {
               func = newStack.shift();
               if (func) func(req, res, next);
               return;
            }
         })();
      });
   }
   return server;
};

我的问题是:我该如何将它与 Express 集成?特别让我困惑的代码部分是底部:

// return a express/connect server with the default middlewares.
// @param serverConstructor = express/connect server instance
// @param options = {
//    root: 'path/to/public/files',
//    maxAge: integer, time in miliseconds ex: 1000 * 60 * 60 * 24 * 30 = 30 days,
//    mime: reference to the mime module ex: require('mime')
// }
// Depends:
//    express or connect server
//    mime module [optional]

h5bp.server = function (serverConstructor, options) {
   var server = serverConstructor.createServer(),
       stack = [
         this.suppressWww(true),
         this.protectDotfiles(),
         this.blockBackupFiles(),
         this.crossDomainRules(),
         this.ieEdgeChromeFrameHeader()
      //,this.expireHeaders(options.maxAge),
      // this.removeEtag(),
      // this.setContentType(require('mime'))
       ];
   // express/connect
   if (server.use) {
      stack.unshift(serverConstructor.logger('dev'));
      stack.push(
         //serverConstructor.compress(), // express doesn't seem to expose this middleware
         serverConstructor['static'](options.root, { maxAge: options.maxAge }), // static is a reserved
         serverConstructor.favicon(options.root, { maxAge: options.maxAge }),
         serverConstructor.errorHandler({
            stack: true,
            message: true,
            dump: true
         })
      );
      for (var i = 0, len = stack.length; i < len; ++i) server.use(stack[i]);
   } else {
      server.on('request', function (req, res) {
         var newStack = stack,
             func;
         (function next (err) {
            if (err) {
               throw err;
               return;
            } else {
               func = newStack.shift();
               if (func) func(req, res, next);
               return;
            }
         })();
      });
   }
   return server;
};

我的 JavaScript 不完全处于初学者水平,但我也不会说我很高级。这段代码超出了我的范围。任何关于我可以阅读、观看或做什么的指示,以了解我在这里显然缺少的东西,我们将不胜感激。

最佳答案

Most of the file由一系列为框架生成中间件的函数组成,如Express,符合Connect的中间件规范。第二个代码 list 旨在创建一个使用所有这些功能的 HTTP 服务器。据我所知,您似乎应该传递通常称为 createServer 的任何内容。打开,h5bp 将为您创建和设置。例如,如果您通常会这样做:

var express = require('express');
var server = express.createServer();

您将改为传递 expressh5bp.server ,它调用 createServer无论你立即通过什么:

var express = require('express');
var server = h5bp.server(express, options);

经过一些设置后,它会检查服务器是否有一个名为 use 的函数(该行是 if (server.use) ),如果是这样,则使用它将它设置的所有中间件注入(inject)服务器。如果它没有,那么它假定您使用的是原始 Node.js HTTP 服务器,并设置必要的代码以通过 stack 中的每个项目传递请求。手动(这就是 Connect/Express 为您所做的)。

值得注意的是,在 Express 3(目前处于发布候选阶段)中,Express 创建的应用程序不再继承自 Node 的 HTTP 服务器,因此您无需调用 createServerexpress ;相反,你应该调用 express()然后将结果传递给 http.createServer . (有关详细信息,请参阅 Migrating from 2.x to 3.x on the Express wiki 中的“应用程序功能”。)这意味着此脚本与最新版本的 Express 不兼容。

[更新]

如果你看一下test GitHub上的目录,可以看到an example app :

var express = require('express'),
   h5bp     = require('../node.js'),
   server   = h5bp.server(express, { 
      root: __dirname,
      maxAge: 1000 * 60 * 60 * 30
   });

server.listen(8080);
console.log('ok');

关于Node.js HTML5 样板服务器配置集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11911556/

相关文章:

node.js - Postman 向 NodeJS 中的 API 发出的 POST 请求中的正文为空(但不是来自自动化测试)

node.js - Npm 无法进行身份验证,您的身份验证 token 似乎无效

node.js - 带有 node-jwt-simple 的本地 Passport

javascript - 在 WebStorm 上远程运行 node.js 应用程序?

node.js - 通过 cookie 为 Node.js 集群提供粘性 socket.io session ,无需粘性 Express session

node.js - 如何动态刷新 EJS 标签中的 JSON 数据

javascript - Spring 和 React 集成

javascript - 使用 jQuery UI Accordion 和 javascript 在正文中加载来防止 FOUC

twitter-bootstrap - Initializr 上的 "Mobile-first Responsive"和 "Twitter Bootstrap"有什么区别?