如何在需要等待内容加载的动态页面上使用JSON-LD添加结构化数据?

16
我正在开发一个网站,想要在详细页面中添加结构化数据。问题是,在不知道要添加到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()方法在两个地方被调用。如果我在一开始就立即调用它,那么使用谷歌结构化数据测试工具时,我可以追踪到所需的结构化数据,没有问题。然而问题在于,此时我还没有创建结构化数据所需的信息,因为需要等待来自Parse的响应。

当我在成功回调中调用该方法时,测试工具无法再检索到数据 :(


嘿,Mousey,谢谢你,我找到了你提供的答案。问题是,在创建JSON-LD之前,我需要等待请求的响应。如果我将答案中的代码添加到js文件中,则结构化数据不会出现。 - AlexBalo
你只需要使用window.onload$(document).ready()来等待DOM准备就绪,将创建JSON-LD的部分放在其中。https://dev59.com/A3RA5IYBdhLWcg3w2x6W - Mousey
哦!谢谢Mousey,我会尝试并给你反馈的!! - AlexBalo
谢谢Mousey,但是即使按照你的建议,我仍然无法达到预期的结果:( - AlexBalo
1
@AlexBalo,你得到了完美的答案吗?如果你能解决使用ajax响应创建的json-ld问题,我需要一些帮助。我无法在Google上看到更新的结果,甚至在Google结构化工具中也没有。 - Parth Trivedi
显示剩余4条评论
2个回答

23

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-LD playground检查的JSON字符串中删除了换行符。


1
好的,太好了Mousey,我会在今晚回家后检查这个答案。对于el变量,我可能只是复制粘贴错误。我会尽快给你反馈。 - AlexBalo
1
@AlexBalo - 这就是为什么你需要检查DOM以获取动态创建的JSON-LD代码,然后你可以将其复制到Google测试工具中,或者创建一个包含该代码的测试页面并进行爬取,然后查看是否出现(我的花了2天时间)。Google的工具不会检查动态代码,结构化数据验证工具也不会。 - Mousey
你的原始问题是如何在 DOM 加载后动态地创建 JSON-LD。这个脚本可以做到,因为它在文档 ready jQuery 命令之后运行。只需在调用 Stringify 之前将您的额外代码添加到新脚本中,并将变量作为内容的一部分使用。尽管该工具仅可用于测试静态结构化数据,但搜索引擎仍然可以理解 JSON-LD。一个简单的检查是将修改后的数据设置为(计算出的)文档的修改日期,并使用一个变量。 - Mousey
1
啊,好的,你的意思是使用谷歌工具无法检索到它,但如果我在DOM中看到它,就意味着搜索引擎可以理解它,对吗?例如,我可以在大约2天后在我的搜索控制台中检查它,正确吗? - AlexBalo
1
谢谢Mousey的帮助! - AlexBalo
显示剩余6条评论

0

我认为Mousey已经完美地回答了这个问题,我要分享一个类似的场景,在页面上加载航班详情,但是在获取价格时我们调用API,因此当我们获得价格时,我们必须动态加载模式。

我们创建了一个嵌套函数,在页面加载时调用它并传递航班细节,然后在调用 "priceGraber" API (获取航班价格) 时,一旦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); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接