Javascript ExpressJS&;Swig:根据路线更改模板变量?

Javascript ExpressJS&;Swig:根据路线更改模板变量?,javascript,node.js,express,meanjs,Javascript,Node.js,Express,Meanjs,我正在使用MEAN.js开发一个应用程序,我正在尝试修复文章(博客),这样它对社会共享更友好。我遇到的问题是填充open graph元数据,以便它使用共享的实际url填充og:url值。以下是文件的外观: express.js // Setting application local variables, to be rendered in the template's variables in layout.server.view.html below. app.locals.siteName

我正在使用MEAN.js开发一个应用程序,我正在尝试修复文章(博客),这样它对社会共享更友好。我遇到的问题是填充open graph元数据,以便它使用共享的实际url填充og:url值。以下是文件的外观:

express.js

// Setting application local variables, to be rendered in the template's variables in layout.server.view.html below.
app.locals.siteName = config.app.siteName;
app.locals.title = config.app.title;
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.imageUrl = config.app.imageUrl;
app.locals.facebookAppId = config.facebook.clientID;
app.locals.jsFiles = config.getJavaScriptAssets();
app.locals.cssFiles = config.getCSSAssets();

// Passing the request url to environment locals
app.use(function(req, res, next) {

    // NOTE: This is the line that's setting the url on the layout template.
    res.locals.url = req.protocol + '://' + req.headers.host + req.url;
    next();
});
// Accessed only when a user visits one of the 'Articles' (blog) pages.
// When a user visits a url for an Article, this file grabs the article
// from the database and updates the local variables with article-specific
// values. This works for everything EXCEPT the url variable.

exports.articleByUrl = function(req, res, next, id) {
    var url = req.params.articleUrl;
    Article.findOne({urlTitle: url}).populate('user', 'displayName').exec(function(err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + id + ' with friendly URL "' + url + '".'));
        req.app.locals.title = article.title;
        req.app.locals.description = article.summary;

        // This is the line that I'm HOPING will update the url variable in
        // the template file above, but it's not working. I've also tried
        // using req.app.locals.url, but that didn't work either.
        res.locals.url = req.protocol + '://' + req.get('host') + '/#!' + req.originalUrl;

        req.app.locals.imageUrl = article.img;
        req.article = article;
        next();
    });
};
layout.server.view.html

// This is the template being rendered, using Swig as the template engine.
// The variables (e.g. siteName, title, etc.) are being set using the app.locals and req.locals.url variables in the express.js file above.

<!-- Facebook META -->
<meta id="fb-app-id" property="fb:app_id" content="{{facebookAppId}}">
<meta id="fb-site-name" property="og:site_name" content="{{siteName}}">
<meta id="fb-title" property="og:title" content="{{title}}">
<meta id="fb-description" property="og:description" content="{{description}}">
<meta id="fb-url" property="og:url" content="{{url}}">
<meta id="fb-image" property="og:image" content="{{imageUrl}}">
<meta id="fb-type" property="og:type" content="website">

<!-- Twitter META -->
<meta id="twitter-title" name="twitter:title" content="{{title}}">
<meta id="twitter-description" name="twitter:description" content="{{description}}">
<meta id="twitter-url" name="twitter:url" content="{{url}}">
<meta id="twitter-image" name="twitter:image" content="{{imageUrl}}">
目前,除url值外,所有值都正确填充-它始终显示根url(即在我的开发人员机器上)。任何帮助,或者更聪明的方法来做我想做的事,我都会非常感激。我花了两天时间在这上面,我的固执终于消失了。

当你使用:

req.app.locals
它会为每个人更改应用程序的所有值(直到服务器重新启动)。正确的方法是使用:

res.app.locals
但是,当您这样做时,它只对初始页面请求执行,并且在客户端应用哈希更改时不会持久化

建议的方法是使用所讨论的URL创建一个新的服务器布局文件,这样就不会有散列更改,那么新服务器模板文件的导航可能会链接回单页应用程序中的URL(使用原始服务器模板)


祝你好运。您能否检查代码并查看
res.locals.url
是否正确分配了预期值?您如何使用
articleByUrl()
?如果它是一个合适的中间件,那么它的使用顺序就很重要(一些
console.log
语句将显示哪个称为last:
articleByUrl
或您的“通用”中间件)。此外,您正在使用请求相关信息覆盖
req.app.locals
。这将导致多个并发请求出现未定义的行为(尽管这很可能不是您描述的问题的原因)。@GPX这是一个好问题-从技术上讲
res.locals.url
是正确的,因为这是查找
articleByUrl()
的路径。但这不是用户看到的最终url,因为Angular执行实际的路由。@robertklep是的,据我所知,它是合适的中间件。我已经为这两个函数插入了日志语句,并且在我的express.js文件中更一般的
res.locals.url
之后会打印
articleByUrl()。这是让我如此困惑的一部分——我希望它会覆盖一般的,但似乎不是。至于使用
req.app.locals
,我这样做是因为
req.locals.title
抛出了一个错误。如果它只是app的一个
req
实例,那么这仍然是并发请求的一个原因吗?(你是指来自多个用户,还是来自一个用户的并发请求?)@aikorei
req.locals
应该是
res.locals
,这样可以解释抛出的错误
req.app
指向“全局”
app
对象,因此对
req.app.local
的任何更改都会反映在整个应用程序和所有请求中。因此,当请求A几乎同时进入时,请求B可能会覆盖请求A设置的值(无论它们是否由同一用户启动)。