【发布时间】:2015-08-13 02:43:04
【问题描述】:
我正在使用 MEAN.js 开发一个应用程序,并且我正在尝试修复文章(博客),以便它对社交分享更加友好。我遇到的问题是填充打开的图元数据,以便使用共享的实际 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();
});
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}}">
articles.server.controller.js
// 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();
});
};
目前,除了 url 值之外,所有值都正确填充 - 它始终显示根 url(即我的开发机器上的 http://localhost:3000)。任何帮助,或更聪明的方法来做我想做的事,我都会非常感激。我花了2天的时间,我的固执终于放弃了。
【问题讨论】:
-
你能检查你的代码,看看
res.locals.url是否被正确分配了预期的值? -
您如何使用
articleByUrl()?如果它是一个合适的中间件,那么它是use()'d 的顺序很重要(一些console.log语句将显示最后调用的:articleByUrl或您的“通用”中间件)。此外,您正在使用依赖于请求的信息覆盖req.app.locals。这将导致多个并发请求的未定义行为(尽管这很可能不是您描述的问题的原因)。 -
@GPX 这是一个很好的问题——技术上
res.locals.url是正确的,因为Angular 是通过GET找到articleByUrl()。但这不是用户看到的最终 url,因为 Angular 执行实际路由。 -
@robertklep 是的,据我所知,它是合适的中间件。我已经为这两个函数插入了日志语句,
articleByUrl()在我的 express.js 文件中更通用的res.locals.url之后打印。这是让我非常困惑的部分原因 - 我期望它会覆盖一般的,但似乎并非如此。至于使用req.app.locals,我这样做是因为req.locals.title会抛出错误。如果它只是一个应用程序的req实例,这仍然是并发请求的一个原因吗? (你的意思是来自多个用户,还是来自 1 个用户的并发请求?) -
@aikorei
req.locals应该是res.locals,这样就可以解释抛出的错误;req.app指向“全局”app对象,因此对req.app.local的任何更改都会反映在整个应用程序和所有请求中。因此,当请求 B 几乎同时进入时,请求 B 可能会覆盖请求 A 设置的值(无论它们是否由同一用户发起)。
标签: javascript node.js express meanjs