首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MEAN.js社交分享?

MEAN.js社交分享?
EN

Stack Overflow用户
提问于 2015-06-02 19:43:49
回答 2查看 1.1K关注 0票数 4

因此,我用MEAN.js创建了一个应用程序,并对文章(博客)部分进行了一些更新,以获得更好的搜索引擎优化、可读性、设计等。不过,我似乎无法理解的一个问题是,如何使用Facebook、Google+、Twitter等共享文章,并让它们使用og meta标记填充正确的数据。

我想要什么

我想要的只是能够分享我的MEAN.js应用程序中的文章(博客文章),并且当我在社交网站(例如Facebook)上发布链接时,文章内容会显示出来。

我已经尝试过的

我尝试为博客文章创建一个单独的服务器布局,但这打破了很多其他东西,我意识到工作量可能不值得--必须有一个更聪明的方法。

我也尝试过用客户端的角度更新og元标记数据,但是在社交网站获取那些tags...in之前,这些值不能更新--换句话说,它并没有做我想做的事情。

当索引呈现时,我尝试抓取角路由URL,以便在呈现索引之前更新那些og元值,但是在req数据中任何地方都找不到这些值。

我认为问题是

从概念上讲,这就是我认为正在发生的事情:

  1. 请求到达我的服务器,但是由于它是一个使用角路由的单一页面应用程序,所以req.url值只是根页('/')。
  2. 将加载索引文件,该文件使用标准服务器模板布局。
  3. 角得到加载并进行AJAX调用以获取文章数据,然后将该数据绑定到页面上的变量。

因此,基本上,布局是在角度之前(使用og元值)呈现的,甚至在确定要获取的文章信息之前。

我猜理想的解决方案是

在我的express.js文件中,应用程序的局部变量设置如下:

代码语言:javascript
复制
// Setting application local variables
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();

然后由Swig在layout.server.view.html文件中呈现这些局部变量,如下所示:

代码语言:javascript
复制
// Note the {{keywords}}, {{description}}, etc. values. 
<!-- Semantic META -->
<meta id="keywords" name="keywords" content="{{keywords}}">
<meta id="desc" name="description" content="{{description}}">

<!-- 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}}">

因此,理想情况下,我认为我们希望在呈现页面之前使用特定于文章的信息更新这些值。问题是,如果布局在显示角度之前就被呈现,那么我如何才能找到要填充的项目数据?同样,角路径似乎在req对象中的任何位置都不可用,所以我完全不知道如何做到这一点。

因此,我回到了我最初的愿望--如何使用MEAN.js以“漂亮”的方式在社交媒体上分享我的文章?我在正确的轨道上吗?是否可以使用当前的项目设置?我是否需要构建一个完全没有角度的博客模块?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-21 20:03:28

我终于在没有Nginx或MEANJS框架之外的其他任何东西的情况下,为我的应用程序做到了这一点。你的里程可能不一样,但我还是想和你分享结果。它对我有用,但对你可能不管用。

基本上,我已经设置了一种获取非散列URL并重定向到散列URL的方法。因此,用户可以共享他们的配置文件,例如example.com/myprofile,它将重定向到example.com/#!/profile/myprofile

然后,我严格地为社交机器人创建了一个单独的布局(但回想起来,我不确定这是完全必要的),并在站点被刮掉时为单独的布局提供服务。我是这样做的:

social-layout.server.view.html

代码语言:javascript
复制
...some stuff here...
//Note the variable names, e.g. {{siteName}}
<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="{{socialTitle}}">
<meta id="fb-description" property="og:description" content="{{socialDescription}}">
<meta id="fb-url" property="og:url" content="{{socialUrl}}">
<meta id="fb-image" property="og:image" content="{{socialImageUrl}}">
<meta id="fb-type" property="og:type" content="website">

...other stuff here...

然后在我的Express文件中,显式地检查user-agents以确定是否需要新的布局。如果我找到一个bot,我从我的DB中获取一些与URL相关的关键数据,然后填充这些变量,如下所示:

express.js

代码语言:javascript
复制
// This code happens just after app.locals variables are set.
    // Passing the request url to environment locals
    app.use(function(req, res, next) {
        // Let's check user-agents to see if this is a social bot. If so, let's serve a different layout to populate the og data so it looks pretty when sharing.
        if(req.headers['user-agent'] === 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)' ||
            req.headers['user-agent'] === 'facebookexternalhit/1.0 (+http://www.facebook.com/externalhit_uatext.php)' ||
            req.headers['user-agent'] === 'facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)' ||
            req.headers['user-agent'] === 'facebookexternalhit/1.0 (+https://www.facebook.com/externalhit_uatext.php)' ||
            req.headers['user-agent'] === 'visionutils/0.2' ||
            req.headers['user-agent'] === 'Twitterbot/1.0' ||
            req.headers['user-agent'] === 'LinkedInBot/1.0 (compatible; Mozilla/5.0; Jakarta Commons-HttpClient/3.1 +http://www.linkedin.com)' ||
            req.headers['user-agent'] === 'Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20110814 Firefox/6.0 Google (+https://developers.google.com/+/web/snippet/)' ||
            req.headers['user-agent'] === 'Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)') {

            var urlAttempt = req.url;
            urlAttempt = urlAttempt.substr(1);

            Users.findOne({ link: urlAttempt }, function(err, results) {
                if(err) {
                    res.locals.url = req.protocol + '://' + req.headers.host;
                    next();
                } else if (results !== null) {
                    // Found link. Populate data.
                    res.status(200).render('social-index', {

                        // Now we update layout variables with DB info.
                        socialUrl: req.protocol + '://' + req.headers.host + req.url,
                        socialTitle: results.orgName,
                        socialDescription: results.shortDesc,
                        socialImageUrl: req.protocol + '://' + req.headers.host + '/profile/img/' + results.imgName
                    });
                } else {
                    res.locals.url = req.protocol + '://' + req.headers.host;
                    next();
                }
            });
        } else {
            res.locals.url = req.protocol + '://' + req.headers.host;
            next();
        }
    });

再说一遍,你的里程可能不同,但这对我(部分)有效。我仍在致力于共享整个URL (包括哈希)。希望能在某种程度上有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2015-06-15 13:46:37

我也面临过同样的问题。首先我安装了Mean模块。你可以在mean.js官方github回购网站上找到它。模块本质上就是这样做的:爬虫(Google等)当他们遇到SPA时,向他们的请求添加一个_escaped_fragment_部件。均值-Seo拦截请求,其中包括_escaped_fragment_。然后使用Phantom.Js,从动态HTML中呈现一个静态HTML并保存它,将这个静态版本提供给爬虫器。

对于Facebook和Twitter,我更改了mean-seo.js文件Mean,在它缓存和保存静态文件之前,我相应地替换了元标记。因为Phantom.Js已经呈现了整个文章页面,所以您不需要进行另一个API调用。解析HTML就行了。我还使用cheerio.js来方便地解析HTML。

这样解决了我的问题,但不是很完美。我仍然在挣扎于hashbang & HTML5模式。当我的网址类似于https://example.com/post/1时,Twitter和Facebook不请求_escaped_fragment_

更新:一段时间后,我放弃了这一程序。Phantomjs看起来不可靠,我不喜欢浪费系统资源、CPU时间、RAM、磁盘空间来完成这样的任务。不必要的文件创建也是愚蠢的。我目前的做法如下:

我为Twitter和Facebook添加了一条新的快车路线。在服务器控制器中,实现了一个新的爬虫功能。创建了一个简单的服务器模板,没有棱角、引导和所有这些闪亮的东西:只有元标签和简单的文本。使用Swig (已经包含在Meanjs中),相应地呈现此视图模板。我还使用Nginx作为代理。因此,我基于用户代理定义了一个新的Nginx rewrite。就像这样:

代码语言:javascript
复制
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
    rewrite ^/posts/(.*)$ /api/posts/crawl/$1 last;
    }

当一个爬虫请求一个帖子的URL时,Nginx会触发我的新的简单爬虫路径,并生成一个很小的页面。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30605210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档