3

我需要检查每个页面请求的请求标头。我认为尝试这个的地方是'撇号-快递'模块。我创建了自己的模块“auth”,它扩展了“撇号-express”:

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

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

你能告诉我我应该在哪里挂钩每个页面请求以运行一些自定义检查/规则(例如,如果某个 cookie 不存在,则将用户重定向到不同的站点)?

谢谢!

4

1 回答 1

5

我是朋克大道撇号的主要建筑师。

您不想以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();
        }
      ]
    }
  }
});

这就是您所需要的,您可以使用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   
  };
};

在页面渲染之前拦截请求

您指定了“每个页面请求”,我将其解释为“每个 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);
    };
  }
};

撇号总是调用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);
    };
  }
};

请注意,我允许其中一个req.data.pagereq.data.bestPage存在。如果 URL 与页面不完全匹配,Apostrophe 将设置req.data.bestPage为具有与 URL 匹配的最长“路径前缀”的页面。例如,如果 URL 是 /foo/bar 并且 /foo 存在但 /foo/bar 不存在,req.data.bestPage则将为/foo. 请注意,这意味着req.data.bestPage在最坏的情况下将是主页。

请参阅apostrophe-custom-pages模块以了解您可以用它做的整洁的事情。

希望这有帮助!

于 2016-10-01T13:51:53.100 回答