【问题标题】:Facebook sometimes does not fetch Open Graph tagsFacebook 有时不获取 Open Graph 标签
【发布时间】:2017-01-17 18:09:23
【问题描述】:

我有一个用于共享 Facebook 链接的公共图书馆的 iOS 应用。链接指向单个域,其中包含一个相对简单的 PHP 脚本,该脚本根据链接的内容(目录项、日历事件和用户生成的列表)重定向到三个不同的目标域。我之所以这样设置,是因为我使用的是 iOS 通用链接,并且我无法控制所有链接目标,所以我需要一个用于 apple-app-site-association 文件的中心位置。

在这个 PHP 脚本中,我尝试根据共享的内容类型动态设置 OG 标签。这是脚本:

<?php

$shareType = $_GET['t'];
$contentId = $_GET['id'];

$base_catalog_url='XXXXXXXXXXXX';
$base_list_url='XXXXXXXXXXXXX';
$base_event_url='XXXXXXXXXXXXXX';

if($shareType=='0'){
    $oclc;
    if(strlen($contentId)==8){
        $oclc = 'ocm'.$contentId;
    }

    if(strlen($contentId)==9){
        $oclc = 'ocn'.$contentId;
    }

    $url = $base_catalog_url.'searchCatalog?'.http_build_query(array('clientID' =>'sdIPhoneApp','term1'=>$oclc));
    $resp = simplexml_load_file($url);

    $pageTitle = $resp->HitlistTitleInfo->title;
    $isbn = $resp->HitlistTitleInfo->ISBN;
    $imageURL = 'http://www.syndetics.com/index.aspx?isbn='.$isbn.'/lc.gif&client=XXXXXXX';
    $redirectURL =  'XXXXXXXXXXXX'.$contentId;
    error_log($redirectURL);
    echo '<html>
        <head>
            <meta property="og:image" content="'.$imageURL.'" />
            <meta property="og:title" content="'.$pageTitle.'" />
            <meta name="twitter:card" content="summary" />
            <meta name="twitter:site" content="@acpl" />
            <meta name="twitter:title" content="'.$pageTitle.'" />
            <meta name="twitter:description" content="Allen County Public Library" />
            <meta name="twitter:image" content="'.$imageURL.'" />
            <meta http-equiv="refresh" content="0;URL='.$redirectURL.'">
        </head>
     </html>';
}

if($shareType=='1'){
    $url = $base_event_url.http_build_query(array('eventid' =>$contentId));
        $response = file_get_contents($url);
    $json = json_decode($response);
    $event = $json[0];
    $imageURL = $event->Image;
    $pageTitle = $event->Title;
    $description = $event->Description;

    if(strlen($imageURL)<5){
        $imageURL = 'https://XXXXXXXXX/appIcon200.png';
    }

    $redirectURL = 'XXXXXXXXXXX'.$contentId;

    echo '<html>
        <head>
            <meta property="og:image" content="'.$imageURL.'" />
            <meta property="og:title" content="'.$pageTitle.'" />
            <meta property="og:description" content="'.$description.'" />
            <meta name="twitter:card" content="summary" />
            <meta name="twitter:site" content="@acpl" />
            <meta name="twitter:title" content="'.$pageTitle.'" />
            <meta name="twitter:description" content="'.$description.'" />
            <meta name="twitter:text:description" content="'.$description.'" />
            <meta name="twitter:image" content="'.$imageURL.'" />
            <meta http-equiv="refresh" content="0;URL='.$redirectURL.'">
        </head>
     </html>';

}

if($shareType=='2'){

    $url = $base_list_url.http_build_query(array('listId' =>$contentId,'userKey'=>0));
    $response = file_get_contents($url);
    $json = json_decode($response);
    $imageURL = $json->coverImageURL;
    $pageTitle = $json->listName;
    $pageTitle = ucwords(strtolower($pageTitle));

    $redirectURL = "XXXXXXXXXXXX";

    echo '<html>
        <head>
            <meta property="og:image" content="'.$imageURL.'" />
            <meta property="og:title" content="'.$pageTitle.'" />
            <meta name="twitter:card" content="summary" />
            <meta name="twitter:site" content="@acpl" />
            <meta name="twitter:title" content="'.$pageTitle.'" />
            <meta name="twitter:description" content="Allen County Public Library" />
            <meta name="twitter:image" content="'.$imageURL.'" />
            <meta http-equiv="refresh" content="0;URL='.$redirectURL.'">
        </head>
     </html>';

}

?>

因此,根据共享的内容类型,我获取页面标题和图像以在 OG 标签中提供。重定向总是有效的,无论 Facebook 是否拉入标签,但标签只被使用了大约一半的时间。您可以在 iOS 应用程序中看到这一点。成功拉入标签:

标签未拉入:

是否显示给定项目的标签似乎是随机的。在我服务器上的访问日志中,当标签成功显示时,我看到这样一行:

66.220.158.119 - - [09/Sep/2016:09:54:50 -0400] "GET /share.php?t=1&id=76137 HTTP/1.1" 206 3771 "-" "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)"

但是,当标签不显示时,访问日志或错误日志中没有任何内容。这表明 Facebook(或 iOS 中的 Facebook 组件)在这些情况下甚至没有尝试读取标签。这是否意味着 Facebook 错误地认为它已经缓存了这些数据?

另一个有趣的消息是,当我尝试在 Facebook 共享调试器 (https://developers.facebook.com/tools/debug/) 上调试其中一个失败的 URL 时会发生什么。我将收到一条错误消息:

The 'og:image' property should be explicitly provided, even if a value can be inferred from other tags.

当我点击“查看我们的抓取工具为您的 URL 看到的内容”时。我得到响应“文档未返回数据”。

有趣的是,当我单击“再次抓取”时,最初几次通常会出现相同的错误,然后尝试 3 或 4 次后它突然起作用并显示标签。我的第一个想法是,这与我如何动态获取标签的内容有关,但正如我上面提到的,在未显示标签的情况下,访问日志显示 Facebook 甚至没有从我的服务器请求任何东西。

感谢您的帮助;这让我把头发拔了!

更新:如果您想在 Facebook 调试器中试用,这里有一个示例 URL:https://amshare.acpl.lib.in.us/0_930144011

下划线后面的数字是图书的 OCLC 编号,因此您可以在此处插入其他值。正如我所提到的,经过几次刮擦后,它通常会开始工作,然后再无法工作,等等。

【问题讨论】:

  • 基本 URL(没有查询参数)是否总是 share.php?我不确定 Facebook 在确定要缓存的内容时是否考虑附加的参数,所以这可能会导致这种奇怪。
  • 是的,它总是 share.php。我想我可以为每种共享类型(shareItem.php、shareEvent.php)使用不同的脚本,但似乎这会遇到同样的基本问题。
  • 我认为您可能需要为每个链接使用唯一的 URL。如果您查看 URL 缩短器(Bit.ly、Goo.gl 等)和其他依赖于每个 URL 跟踪或动态路由的服务(HubSpot、HootSuite),它们普遍采用这种方式。在Branch.io,我们几乎完全按照您在上面描述的方式进行操作,并且每个链接都带有一个唯一的 URL
  • 如果我这样做了,我就不能使用通用链接了。
  • 应该还是可以的。只需将所有唯一 URL 放在一个目录下(例如,/share/7ahAs7D),然后为该目录中的所有内容启用通用链接。

标签: php ios facebook facebook-opengraph ios-universal-links


【解决方案1】:

我可能是 facebook 缓存了 share.php 文件并忽略了 GET Vars。

您可以尝试将 URL 重写为“漂亮的永久链接”。把它放在你的 htaccess 文件中(如果你有 apache):

Options +FollowSymLinks
RewriteEngine On

RewriteRule ^share/(.*)/(.*)$ share.php?t=$1&id=$2 [L,NC]

这由 http://your-url.com/share/4/yeah 组成:http://your-url.com/?t=4&amp;id=yeah

$_GET 变量如下所示:

Array ( [t] => 4 [id] => yeah )

有了这个你可以解决这个问题(如果它真的是缓存的话)。过去,我在使用 facebook 刮板时遇到了很多问题。有时它会忽略 get vars 并像地狱一样缓存......

【讨论】:

  • 进行此更改后,我看到了相同的行为。另外,我会说这几乎可以肯定是某种缓存问题。正如我上面提到的,在标签不起作用的情况下,访问日志中绝对没有任何内容。因此,在这些情况下,Facebook 不会向我的服务器请求任何内容。
  • 您是否尝试过使用完全相同的 sharer.php url 添加 og:url 元标记? (或者重写,如果你插入了我的 sn-p)?它告诉 FB 抓取其中的 url - 可能它可以解决你的缓存问题?
  • 我试过这个;它导致相同的行为。当我告诉它在调试器上“再次抓取”时,无论它是否有效,它似乎都是完全随机的。
  • 你能把分享的网址贴出来让我测试一下会发生什么吗?
  • 下划线后面的数字是该书的OCLC编号,因此您可以尝试在那里插入其他值。正如我所提到的,经过几次刮擦后,它通常开始工作,然后又无法工作,等等。
【解决方案2】:

尝试在响应中添加一些标头以防止缓存。

缓存控制:无缓存、无存储、必须重新验证 Pragma:无缓存 过期:0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-28
    • 2015-12-08
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    相关资源
    最近更新 更多