Как добавить структурированные данные с помощью JSON-LD на динамические страницы, которым нужно дождаться загрузки содержимого?

Я разрабатываю веб-сайт и хочу добавить структурированные данные на подробные страницы. Проблема в том, что мне нужно запросить данные, прежде чем я знаю, что добавить в сценарий JSON-LD.

Я использую Parse как серверную часть. Я также попытался найти руководства о том, как этого добиться, но мне кажется, что динамическое добавление JSON-LD невозможно.

Я очень надеюсь, что кто-нибудь сможет мне с этим помочь! :)

РЕДАКТИРОВАТЬ:

Ответ с данными, которые мне нужно поместить в JSON-LD, приходит после того, как DOM будет готов. Какова закономерность в этой ситуации?

У меня есть список элементов, и при нажатии на один из них мне нужно открыть страницу с подробностями, которую я должен загрузить в первую очередь, но после загрузки контента я хочу предоставить структурированные данные через JSON-LD.

Я в самом начале, и мне трудно решить эту проблему.

ИЗМЕНИТЬ 2:

Это моя реальная реализация:

В HTML:

<body>
    // my html page code
    ...
    <script type="text/javascript">
        loadDetailPageContent();
    </script>
</body>

В JS:

function loadDetailPageContent() {
    // Calling the method here is too early because I don't have info
    //writeData();
    createDetailPage();
}

function createDetailPage() {
    var recipe = Parse.Object.extend("Recipe");
    var query = new Parse.Query(recipe);
    query.equalTo("objectId", myId);
    query.first({
        success: function(result) {
            // Calling the method here would be perfect
            writeData();
        },
        error: function(error) {
            alert("Error: " + error.code + " " + error.message);
        }
    });
}

function writeData() {
    var script = document.createElement('script');
    script.type = 'application/ld+json';
    script.text = JSON.stringify({
        "@context": "http://schema.org",
        "@type": "Recipe",
        "name": "My recipe name"
    });
    document.querySelector('head').appendChild(el);
}

Как видите, метод writeData () вызывается в двух местах. Если я вызову его сразу в начале, проблем не возникнет, и с помощью инструмента тестирования структурированных данных Google я смогу отслеживать нужные мне структурированные данные. Проблема в том, что в этот момент у меня нет информации для создания структурированных данных, потому что мне нужно дождаться ответа от Parse.

Когда я вызываю метод в обратном вызове успеха, инструмент тестирования больше не может извлекать данные :(


person AlexBalo    schedule 01.08.2015    source источник
comment
Вы можете создать сценарий, который динамически создает JSON-LD, анализатор структурированных данных Google - stackoverflow.com/questions/27169085/javascript-inside-ld-json   -  person Mousey    schedule 01.08.2015
comment
Привет, Мауси, спасибо, я нашел ответ, который ты связал, проблема в том, что мне нужно дождаться ответа на запрос, прежде чем создавать JSON-LD. Если я добавлю код в aswer в js-файле, структурированных данных там не будет.   -  person AlexBalo    schedule 01.08.2015
comment
вам просто нужно использовать window.onload или $(document).ready(), чтобы дождаться готовности DOM, поместите часть, создающую JSON-LD, внутри этого stackoverflow.com/questions/799981/   -  person Mousey    schedule 01.08.2015
comment
Ой! Спасибо, Мыши, я попробую и дам тебе отзыв !!   -  person AlexBalo    schedule 01.08.2015
comment
Спасибо, Мыши, но даже следуя твоему предложению, мне не удалось добиться результата :(   -  person AlexBalo    schedule 02.08.2015
comment
вы можете опубликовать свой код и что показывает загруженный документ DOM?   -  person Mousey    schedule 02.08.2015
comment
Привет, @Mousey, я добавил фрагмент кода, который есть в моей реализации. Надеюсь, это немного прояснит мою проблему :)   -  person AlexBalo    schedule 02.08.2015
comment
Позвольте нам продолжить это обсуждение в чате.   -  person AlexBalo    schedule 02.08.2015
comment
@AlexBalo, вы получили идеальный ответ? Мне потребовалась помощь, если вы решите эту проблему с помощью json-ld, созданного с помощью ответа ajax. Я не вижу обновленных результатов в Google. Не событие в структурированном инструменте Google.   -  person Parth Trivedi    schedule 28.10.2017


Ответы (2)


http://jsfiddle.net/c725wcn9/2/embedded

Вам нужно будет проверить DOM, чтобы убедиться, что это работает. Требуется JQuery.

$(document).ready(function(){
   var el = document.createElement('script');
   el.type = 'application/ld+json';
   el.text = JSON.stringify({ "@context": "http://schema.org",  "@type": "Recipe", "name": "My recipe name" });

   document.querySelector('head').appendChild(el);
});

Ваш код включал имя переменной script, но вместо этого добавлял переменную el к <head>. Также удалены символы новой строки из строки JSON, которая была проверена с помощью JSON-LD Playground.

person Mousey    schedule 04.08.2015
comment
О, хорошо, великий Мышонок, я проверю этот ответ сегодня вечером, когда буду дома. Для переменной el я, вероятно, просто неправильно скопировал и вставил. Я скоро дам вам отзыв. - person AlexBalo; 04.08.2015
comment
Привет, Мауси, я пробовал использовать ваш код, но, к сожалению, инструмент Google для тестирования структурированных данных не может найти мой внедренный json. developers.google.com/structured-data/testing-tool. Я думаю, что проблема связана с тем, что мне нужно дождаться ответа на мой запрос Parse перед инъекцией, и в этот момент страница уже была просканирована на предмет структурированных данных. Мне действительно сложно понять, как это работает. - person AlexBalo; 04.08.2015
comment
@AlexBalo - вот почему вам нужно проверить DOM, чтобы получить динамически созданный код JSON-LD, затем вы можете скопировать его в тестер Google или создать тестовую страницу с кодом и сканировать ее, а затем посмотреть, появится ли она (взял 2 дня у меня). Инструмент Google не проверяет динамический код, как и инструмент линтера структурированных данных. - person Mousey; 04.08.2015
comment
Да, я проверил DOM, и контент добавлен. Но этот JSON-LD всегда разный, и я не могу скопировать его на страницу. Вопрос в том, как сделать мою динамическую страницу с этим кодом, если он каждый раз меняется? - person AlexBalo; 04.08.2015
comment
Ваш исходный вопрос заключался в том, как динамически создавать JSON-LD после загрузки DOM. Этот сценарий делает это, потому что он запускается после команды document readyjquery. Просто добавьте дополнительный код в новый сценарий прямо перед вызовом Stringify и используйте переменные как часть содержимого. JSON-LD будет понят поисковым системам, несмотря на то, что инструмент доступен только для тестирования статических структурированных данных. Простая проверка - установить измененные данные в JSON-LD на (вычисленную) дату изменения документа с помощью переменной. - person Mousey; 04.08.2015
comment
А, хорошо, вы имеете в виду, что с помощью инструмента Google он не будет получен, но если я увижу его в DOM, это означает, что поисковые системы смогут его понять, верно? Могу проверить примерно через 2 дня например в моей поисковой консоли, правильно? - person AlexBalo; 05.08.2015
comment
Спасибо Mousey за помощь! - person AlexBalo; 05.08.2015
comment
@AlexBalo, могу я спросить, сработал ли ваш подход в Google Search Console? Я решаю, какой формат структурированных данных использовать (JSON-LD, Microdata или RDFa), и ваша информация мне (и, возможно, другим) очень поможет. - person Michal Moravcik; 23.01.2017
comment
Привет всем, да, метод у меня сработал. Затем мне пришлось отказаться от Parse, поскольку они закрылись, и я изменил код на веб-сайте. Но я помню, что все работало нормально. - person AlexBalo; 23.01.2018
comment
как это правильный ответ? этот код не отражается в исходном коде страницы и будет виден только внутри инструментов разработчика ... - person popeye; 02.04.2018

Я думаю, что Мыши прекрасно ответил на это, я собираюсь поделиться аналогичным сценарием, где мы загружаем информацию о рейсе на страницу, но по цене мы вызываем API при загрузке страницы, поэтому мы должны загружать схему динамически, когда мы получаем цену.

Мы создали вложенную функцию, которую мы вызываем при загрузке страницы и передаем информацию о рейсе, а затем при загрузке страницы, когда мы вызываем API «priceGraber» (для получения цены на рейс). Как только priceGraber возвращает успешный ответ, мы вводим схему на страницу.

Функция создателя схемы:

    // create product schema
createProductSchema = function(from, to, currency) {
    return injectSchema = function(price) {
        let el = document.createElement('script');
        el.type = 'application/ld+json';
        el.text = JSON.stringify({
            "@context": "https://schema.org/",
            "@type": "Product",
            "name": `Flight from ${from} to ${to}`,
            "description": `Cheap flights from ${from} to ${to}`,
            "offers": {
                "@type": "Offer",
                "url": `http://flightsearches.net?fso=${from}&fsd=${to}`,
                "priceCurrency": `${currency}`,
                "availability": "https://schema.org/InStock",
                "price": `${price}`,
            }
        });

        console.log('inject now ');
        document.querySelector('head').appendChild(el);
    };
};

Информация о передаче при загрузке страницы для схемы, которая доступна при загрузке страницы

сценарий ниже находится внутри файла лезвия, {{$ flight_from}}, {{$ flight_to}} - директивы лезвия (переменные на стороне сервера)

        <script>
    $(function(){
                if(typeof createProductSchema == "function") {
                    console.log('create product schema...');
                    window.injectProductSchema = createProductSchema({{ $flight_from }},  {{ $flight_to }});
                } else {
                    console.error("product schema creator doesn't exists !");
                }
            });

         </script>

Схема динамического внедрения

мы вызываем функцию ниже внутри ответа ajax, где мы получаем API формы "цена", а затем эта функция вызывает вложенную функцию, которая затем добавляет схему в заголовок

window.injectProductSchema(price); 
person Furqan Freed    schedule 01.10.2019