检查每个页面请求上的标题

lan*_*e-p 3 apostrophe-cms

我需要检查每个页面请求上的请求标头。我认为可以在“撇号-表达”模块中进行尝试。我创建了自己的模块'auth',该模块扩展了'apostrophe-express':

module.exports = {
extend: 'apostrophe-express',
name: 'auth',
alias: 'auth',
absoluteUrl: function(req, res, next){
    console.log(req);
 }
};
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。我收到错误信息'apostrophe-templates \ index.js“ 597 req.browserCall('apos.pageReadywhenCalm($(” body“));')'

您能告诉我我应该在每个页面请求中加入哪些位置以运行一些自定义检查/规则(例如,如果不存在某个Cookie,然后将用户重定向到其他站点)?

谢谢!

Tom*_*ell 5

我是P'unk Avenue的Apostrophe的首席建筑师。

您不想apostrophe-express使用新名称扩展模块。该模块提供了apos.app单例,因此以新名称扩展它只会设置apos.app两次,从而导致混乱和潜在问题。

拦截每个Express请求

相反,只需利用模块的middleware选项即可apostrophe-express。您可以在app.js:

var apos = require('apostrophe')({
  modules: {
    // Other module configuration here, then ...
    'apostrophe-express': {
      middleware: [
        function(req, res, next) {
          // Do whatever you like here
          console.log(req.url);
          // Let the request continue. You could also
          // use res.redirect, res.send, etc. and
          // bypass Apostrophe, in which case you
          // should NOT call next
          return next();
        }
      ]
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

这就是您所需要的,您可以用来require从另一个文件中提取中间件功能,从而减少混乱app.js。但是,值得指出的是,您可以将此代码移动到lib/modules/apostrophe-express/index.js项目中的文件中,以“隐式地子类化”该模块。这也为提供您自己的construct属性打开了大门,这将允许您覆盖模块的任何方法(如果需要)。

如果您以这种方式进行处理,则完全不需要触摸app.js:

// in lib/modules/apostrophe-express/index.js at project level
module.exports = {
  middleware: [
    function(req, res, next) {
      console.log(req.url);
      return next();
    }
  ],
  construct: function(self, options) {
    // If you want, override methods of the module here   
  };
};
Run Code Online (Sandbox Code Playgroud)

在页面渲染之前拦截请求

您指定了“每个页面请求”,我将其解释为“每个Web请求”。但是您可能只需要在Apostrophe将要构建并发送适当网页的请求。

为此,只需将pageBeforeSend方法添加到您自己的任何模块中即可。假设我们的模块称为cool-stuff:

// in app.js

var apos = require('apostrophe')({
  modules: {
    // Other module configuration here, then ...
   'cool-stuff': {}
  }
});


// In lib/modules/cool-stuff/index.js

module.exports = {
  construct: function(self, options) {
    self.pageBeforeSend = function(req, callback) {
      // Careful, there isn't always a page object; we could be
      // rendering /login for instance
      console.log(req.data.page && req.data.page._url);
      return callback(null);
    };
  }
};
Run Code Online (Sandbox Code Playgroud)

撇号总是要求pageBeforeSend具有这种方法的每个模块。

如上所示,请注意不要假设req.data.page已设置,因为在少数情况下,Apostrophe会渲染完整的网页作为响应,但在Apostrophe的页面树中没有相应的页面对象。

页面对象加载后立即进行拦截

还有一个选择:如果pageBeforeSend是在你的过程太晚,比如因为你想插件装载机看到您对所做的更改req,使用pageServe,而不是...

// in app.js

var apos = require('apostrophe')({
  modules: {
    // Other module configuration here, then ...
   'cool-stuff': {}
  }
});

// lib/modules/cool-stuff/index.js

module.exports = {
  construct: function(self, options) {
    self.pageServe = function(req, callback) {
      // Express request URL
      console.log(req.url);
      // URL of the best matching page available
      console.log((req.data.page || req.data.bestPage)._url);
      return callback(null);
    };
  }
};
Run Code Online (Sandbox Code Playgroud)

请注意,我允许req.data.page或req.data.bestPage存在。如果URL与页面不完全匹配,则撇号将设置req.data.bestPage为具有与URL匹配的最长“路径前缀”的页面。举例来说,如果URL是/ foo /酒吧/ foo的存在,但/富/条不,req.data.bestPage会/foo。请注意,这意味着req.data.bestPage在最坏的情况下将成为主页。

请参阅该apostrophe-custom-pages模块以获取可以执行的整洁操作。

希望这会有所帮助!