【问题标题】:single page application can't get current page meta tag for facebook share单页应用程序无法获取 Facebook 共享的当前页面元标记
【发布时间】:2014-07-03 09:26:12
【问题描述】:

我正在尝试在我的应用程序中实现 facebook 分享按钮,但我似乎无法让它工作,我想知道为什么这是我到目前为止所拥有的。

html(/post/some-random-string)

<div id="fb-root"></div>
<meta property="og:site_name" content="App">
<meta property="og:url" content="/post/{{data.permalink}}">
<meta property="og:title" content="{{data.title}}">
<meta property="og:type" content="blog">
<meta property="og:image" content="https://i1.ytimg.com/vi/tIWPnxEpNQg/maxresdefault.jpg"> 
<meta property="og:description" content="{{data.preview}}">

<body >
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=580882498674160&version=v2.0";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
   // this facebook share button doesn't appear.
   <div class="fb-share-button" data-href="https://developers.facebook.com/docs/plugins/" data-type="button"></div>
   //so i manually make one.
  <a href="" ng-click='facebookShare();'>Share</a>
 </body>

controller.js

$scope.facebookShare= function(){
   return window.open('http://www.facebook.com/sharer/sharer.php?u='+encodeURIComponent(location.href), 'facebook_share', 'height=320, width=640, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no');
 }

它可以工作,但是它没有读取我在 html 页面上写的元标记,而是从我的索引页面读取

索引页面

<!DOCTYPE html>
<html ng-app='app'>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<noscript>
  <meta http-equiv="refresh" content="7">
    <style type="text/css">
      .pagecontainer {display:none;} 
    </style>
    <div class="pure-u-1 text-center">
    <title>Symsal- Oh no ! We need Javascript to work !</title>
    <h3> Please Enable javascript </h3>
    </div>
</noscript>
  <head>
  <title ng-bind='title'></title>
  // some css file 
  </head>
<body>
<div class='puretype'>
<div ng-controller="MasterCtrl">
<div id="layout">
    <!-- Menu toggle -->
    <a href="" id="menuLink" class=" white menu-link">
        <span></span>
    </a>
<div id='menu' class="pure-u-1">
   <div ng-bind-html="userView"></div> 
</div>
</div>
<div class="pure-g-r">
<div id="feed-container" class='pure-u-1 slide'ng-view=''></div>
</div>
</div>
</div>
// some javascript files 
</body>
</html>

Facebook 调试器

【问题讨论】:

  • developers.facebook.com/debug 说什么?页面的链接是什么?
  • @WizKid 您好,感谢您的回复。我在问题上添加了 facebook 调试器结果
  • 你能不能把网址也加一下,这样我就不用从图片里复制了?
  • URL 可能不同,因为它是来自 localtunnel 的自动生成器链接,但页面相同

标签: javascript html facebook angularjs


【解决方案1】:

jackypan1989 说的是真的,你必须使用绝对网址。 但我很确定会发生的另一件事是 Facebook 不会运行你的 JavaScript 代码,因此这部分是

<meta property="og:url" content="/post/{{data.permalink}}">

永远不会被替换为

<meta property="og:url" content="/post/the-page-that-was-shared">

您遇到的这个问题也可能会阻止 Google 抓取您的网页。

我们遇到了同样的问题,我们使用https://prerender.io 来解决它。 您可以在自己的服务器上使用它,或使用他们的免费/付费服务之一。

【讨论】:

  • prerender.io 如何知道页面何时准备就绪?用 javascript 渲染页面是很容易的部分,但是页面很可能依赖于许多 AJAX 调用,并且您必须知道 AJAX 调用何时已解决
【解决方案2】:

你已经在你的 ng-view 周围定义了一个 body。然后你的视图有它自己的身体。所以你试图在一个不会做你想做的事情的身体内注入一个身体。

请注意,您的控制器不控制包含 Meta 标签的 HTML 元素。它只控制它包含的代码(在您的情况下是主体内的一个 div)。

您可以将控制器添加到 HTML 标记中,也可以使用 $rootScope。

这里有很多答案:How to dynamically change header based on AngularJS partial view?

在处理 ng-view 的控制器中: app.controller('MainControl', function ($rootScope, $scope, Config) { ... $rootScope.canonical = Config.domain; });

我需要动态设置规范链接,但 metas 的主体是相同的。在您的标题中: <link rel="canonical" ng-href="{{ canonical }}" />

您可能希望使用ng-bind 作为元标记。

【讨论】:

    【解决方案3】:

    我会在之前的答案中添加 prerender 将解决爬行问题,但我认为 facebook 分享有点不同(请随时证明我错了 :))。为避免烦人的{{}},您可以定义自己的元指令&lt;meta meta-description&gt; 并使用模板:

    app.directive('metaDescription', [ 'metaData', function(metaData){
      return {
        restrict: 'A',
        replace: true,
        template: '<meta name="description" content="{{metaData.pageDesc}}">',
        link: function(scope,element){
          scope.metaData = metaData;
    
    
        }
      };
    }]);
    

    我们仍然在这里解决 angularJS 的 SEO/共享问题,但这就是我们目前使用的。

    【讨论】:

      【解决方案4】:

      在您的代码中,您应该在 fb-share-button 的 attr 'data-href' 上设置绝对网址。

      例如:

      <div class='fb-share-button' data-href='https://yourabsoluteurl.com' data-type='button'>
      </div>
      

      【讨论】:

        【解决方案5】:

        我使用 express 使它工作。这里可能有一些空白,所以如果有人尝试过,请随时填补 cmets 中的空白,我会更新......

        我在本地两个不同的控制台中同时运行 express 和 react。出于某种原因,我只需要在 prod 中的 express 文件上运行 node。做任何你需要让它运行的事情。这会将请求转发到反应服务器。

        app.get('*', function(req, res) {
            res.sendFile(path.join(__dirname, 'build', 'index.html'));
        });
        

        然后我有一个我共享的页面的路由,看起来像这样。

        app.get('/details/:itemId', function(req, res) {
            const fileName = path.join(__dirname, 'build', `${req.params.itemId}.html`);
            var fileContents = fs.readFileSync(path.join(__dirname, 'build', 'index.html'), 'utf8');
            fileContents = fileContents.replace("og tags", "new values");
            fs.writeFileSync(fileName, fileContents);
            res.sendFile(fileName);
        });
        

        您可能希望搜索该文件并首先提供该文件(如果存在),这样您就不会遇到多个客户端在大容量环境中同时写入同一个文件的问题。或者更好的是,在内存中进行。请记住,express 中的顺序很重要,因此您确实需要在 express 文件中颠倒这两个函数的顺序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-12-23
          • 2014-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多