Facebook иногда не получает теги Open Graph

У меня есть приложение iOS для публичной библиотеки, которое делится ссылками на Facebook. Ссылки указывают на один домен, который содержит относительно простой PHP-скрипт, перенаправляющий на три разных целевых домена на основе связанного содержимого (элементы каталога, события календаря и списки, созданные пользователями). Я настроил его так, потому что я использую универсальные ссылки iOS и не могу контролировать все места назначения ссылок, поэтому мне нужно центральное расположение для файла ассоциации сайта-приложения-яблока.

В этом 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 (или компонент Facebook в iOS) даже не пытается читать теги в этих случаях. Означает ли это, что Facebook ошибочно считает, что эти данные кэшированы?

Еще один интересный момент — это то, что происходит, когда я пытаюсь отладить один из этих неудачных URL-адресов в отладчике обмена Facebook (https://developers.facebook.com/tools/debug/). Я получу сообщение об ошибке в строках:

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

И когда я нажимаю «Посмотрите, что наш парсер видит для вашего URL». Я получаю ответ «Документ не вернул данных».

Интересно то, что когда я нажимаю "Очистить еще раз", он обычно первые несколько раз выдает ту же ошибку, затем после 3 или 4 попыток он внезапно работает и отображаются теги. Моя первая мысль заключается в том, что это связано с тем, как я динамически извлекаю содержимое для тегов, но, как я уже отмечал выше, в случаях, когда теги не отображаются, журнал доступа показывает, что Facebook даже не запрашивая что-либо с моего сервера.

Спасибо за вашу помощь; это заставляет меня рвать на себе волосы!

ОБНОВЛЕНИЕ: Вот пример URL-адреса, если вы хотите попробовать его в отладчике Facebook, если хотите: https://amshare.acpl.lib.in.us

Число после подчеркивания — это номер OCLC книги, поэтому вы можете вставить туда другие значения. Как я уже упоминал, после нескольких царапин он обычно начинает работать, затем снова не работает и т. д.


person James Harpe    schedule 09.09.2016    source источник
comment
Является ли базовый URL-адрес (без параметров запроса) всегда share.php? Я не уверен, учитывает ли Facebook добавленные параметры при определении того, что кэшировать, так что это может быть причиной этой странности.   -  person Alex Bauer    schedule 09.09.2016
comment
Да, это всегда share.php. Я полагаю, что мог бы использовать разные сценарии для каждого типа общего доступа (shareItem.php, shareEvent.php), но похоже, что это будет страдать от одной и той же основной проблемы.   -  person James Harpe    schedule 09.09.2016
comment
Я думаю, вам может понадобиться использовать уникальные URL-адреса для каждой ссылки. Если вы посмотрите на сокращатели URL-адресов (Bit.ly, Goo.gl и т. д.) и другие службы, которые полагаются на отслеживание отдельных URL-адресов или динамическую маршрутизацию (HubSpot, HootSuite), они повсеместно делают это таким образом. На Branch.io мы делаем почти то же, что вы описали выше, и каждая ссылка всегда имеет уникальный URL.   -  person Alex Bauer    schedule 09.09.2016
comment
Если я это сделаю, то не смогу использовать универсальные ссылки.   -  person James Harpe    schedule 09.09.2016
comment
Должен еще уметь. Просто поместите все уникальные URL-адреса в один каталог (например, /share/7ahAs7D), а затем включите универсальные ссылки для всего в этом каталоге.   -  person Alex Bauer    schedule 09.09.2016
comment
Раньше я использовал tinyurl и не мог заставить работать универсальные ссылки с этим. Этот ТАК вопрос (на который вы ответили :)), кажется, предполагает, что это невозможно. stackoverflow.com/questions/36225871/   -  person James Harpe    schedule 09.09.2016
comment
Я думаю, что вы правы, если бы я мог заставить это работать с универсальными ссылками, это могло бы решить вышеуказанную проблему.   -  person James Harpe    schedule 09.09.2016
comment
Ах, да, это не сработает, потому что вы не контролируете домен Tinyurl и не можете связать его со своим приложением. Вам нужно будет настроить уникальные строки ссылок на вашем собственном сервере/домене. Вы также можете попробовать службу связывания Branch, так как она сможет сделать это за вас.   -  person Alex Bauer    schedule 09.09.2016
comment
Я собираюсь рассмотреть возможность перезаписи URL-адресов в качестве возможного обходного пути. Спасибо, что указали мне правильное направление!   -  person James Harpe    schedule 09.09.2016
comment
@AlexBauer Боюсь, не повезло. Я переписываю URL-адреса, чтобы они выглядели как XXXX/type/idnumber, поэтому каждый URL-адрес уникален, но я все равно получить такое же поведение. Я буду придерживаться этих URL-адресов, потому что они короче, но исходная проблема остается.   -  person James Harpe    schedule 09.09.2016
comment
Хм, тогда я должен сдаться — я, честно говоря, не знаю, что может быть причиной этого.   -  person Alex Bauer    schedule 10.09.2016
comment
он больше не обращается к вашему серверу, потому что думает, что это тот же URL-адрес ресурса без идентификатора сеанса или посторонних параметров. Все публикации на Facebook будут использовать этот URL-адрес в качестве идентификационного URL-адреса для этой статьи. но я вижу, что вы попробовали этот подход.. может быть, попробуйте удалить косые черты и изменить подчеркивание... так как он все равно может не работать в разделе «Неверный URL-адрес». , а не для всех пользователей, поделившихся этой статьей. developers.facebook.com/docs/sharing/best-practices#tags   -  person Pawel Dubiel    schedule 14.09.2016
comment
Также проверьте свой хостинг, возможно, он блокирует подобные запросы, отправленные от ботов в течение короткого промежутка времени, с помощью какой-то программы failt2ban.   -  person Pawel Dubiel    schedule 14.09.2016
comment
@PawelDubiel Я изменил косую черту на подчеркивание, но все равно получаю то же поведение.   -  person James Harpe    schedule 14.09.2016


Ответы (2)


Возможно, 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&id=yeah

Переменная $_GET выглядит так:

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

С этим вы можете решить эту проблему (если это ДЕЙСТВИТЕЛЬНО кеширование). В прошлом у меня было много проблем со скребком facebook. иногда он игнорирует get vars и кеширует как черт...

person Adrian Lambertz    schedule 14.09.2016
comment
Я вижу такое же поведение после внесения этого изменения. Кроме того, я бы сказал, что это почти наверняка какая-то проблема с кэшированием. Как я упоминал выше, в тех случаях, когда теги не работают, в логах доступа абсолютно ничего нет. Таким образом, в этих случаях Facebook ничего не запрашивает с моего сервера. - person James Harpe; 14.09.2016
comment
Вы пытались добавить метатег og:url с точно таким же URL-адресом sharer.php? (или переписали, если вы вставили мой фрагмент)? Он говорит FB очистить URL-адрес в нем - возможно, это может решить вашу проблему с кэшированием? - person Adrian Lambertz; 14.09.2016
comment
Я пробовал это; это приводит к тому же поведению. Когда я говорю ему снова очистить отладчик, кажется совершенно случайным, работает он или нет. - person James Harpe; 14.09.2016
comment
Можете ли вы опубликовать URL-адрес для общего доступа, чтобы я мог проверить, что происходит? - person Adrian Lambertz; 15.09.2016
comment
Число после подчеркивания — это номер OCLC книги, так что вы можете попробовать подставить туда другие значения. Как я уже упоминал, после нескольких царапин он обычно начинает работать, затем снова не работает и т. д. - person James Harpe; 15.09.2016
comment
Я проверил с помощью curl код состояния: curl https://amshare.acpl.lib.in.us/0_930144011 -A "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)" -I. Я заметил, что многие мои запросы не выполняются с этим кодом ошибки: curl: (6) Could not resolve host: amshare.acpl.lib.in.us. Можете ли вы проверить, что у вас нет проблем с DNS или чем-то еще? Очень странное поведение. Я думаю, что это вызывает вашу проблему, потому что обычный Facebook Scrap работает без проблем... - person Adrian Lambertz; 16.09.2016
comment
Давайте продолжим обсуждение в чате. - person Adrian Lambertz; 16.09.2016

Попробуйте добавить несколько заголовков в свой ответ, чтобы предотвратить кеширование.

Cache-Control: без кэша, без сохранения, необходимо перепроверить Прагма: без кэша Срок действия: 0

person Jeremy Giberson    schedule 17.09.2016