问题描述
<c:forEach items="${breadcrumbArray}" var="breadcrumb" varStatus="loopCounter">
<c:if test="${breadcrumb ne 'store'}">
<li class="breadcrumb__item">
<c:choose>
<c:when test="${not loopCounter.last}">
<a href="/${breadcrumb}">${breadcrumb}</a>
</c:when>
<c:otherwise>
${fn:replace(breadcrumb,'-',' ')}
</c:otherwise>
</c:choose>
</li>
</c:if>
</c:forEach>
用于动态生成架构的Javascript
<script type="text/javascript">
$(document).ready(function(){
var el = document.createElement('script');
el.type = 'application/ld+json';
el.text = JSON.stringify({ "@context": "https://schema.org/","@type": "BreadcrumbList","itemListElement": [{
"@type": "ListItem","position": 1,"name": "","item": ""
}]
});
document.querySelector('head').appendChild(el);
});
</script>
例如“主页>我们的使命>我们是谁”的架构应该像这样生成:
<script type="application/ld+json">
{
"@context": "https://schema.org/","itemListElement": [{
"@type": "ListItem","name": "Home","item": "https://corp.com/"
},{
"@type": "ListItem","position": 2,"name": "Our Mission","item": "https://corp.com/our-mission/"
},"position": 3,"name": "Who We Are","item": "https://corp.com/our-mission/who-we-are"
}]
}
</script>
脚本没有附加到“head”标签..
解决方法
这个有几个部分。
第一:脚本没有被附加到 `head` 标签
这可能需要更多信息,您的代码中的内容至少应在您的 script
中呈现 JSON-LD head
标记。您的环境中可能发生了一些事情,阻止您写入 head
。您可以尝试将代码更改为:
document.head.appendChild(el)
或 document.getElementsByTagName('head')[0].appendChild(el)
(如果您需要支持旧浏览器)。
可以在这些 SO 线程中找到更多信息:
- Using document.head.appendChild() to append a script tag that has an SRC attribute?
- document.head v. document.getElementsByTagName("head")[0]
再次,我怀疑这就是问题所在。我还会尝试在页面上的其他地方呈现 script
而不是 head
以查看它是否适合您(也相关,请参阅本答案末尾的最后说明)。
第二:使用 JavaScript 创建 JSON-LD
这里有一个粗略的、无 jQuery 但兼容 ES5 的解决方案,用于说明如何生成此内容:
HTML
<ol class="breadcrumbs">
<li class="breadcrumb-item">
<a class="breadcrumb-link" href="https://mypage.com/page1">Page 1</a>
</li>
<li class="breadcrumb-item">
<a class="breadcrumb-link" href="https://mypage.com/page2">Page 2</a>
</li>
<li class="breadcrumb-item">
<a class="breadcrumb-link" href="https://mypage.com/page3">Page 3</a>
</li>
</ol>
<!-- Testing Purposes -->
<div class="output"></div>
JavaScript
// Create Script
var el = document.createElement('script');
el.type = 'application/ld+json';
// Set initial position
var position = 0;
// Create breadcrumb object
var breadcrumb = {
position:0,name:"",item:""
}
// Empty array for list items
var listArray = []
// Loop through each breadcrumb link and set attributes
var items = document.querySelectorAll('.breadcrumb-link');
for(var i = 0; i < items.length; i++) {
var newItem = Object.create(breadcrumb);
var curItem = items[i];
newItem["@type"] = "ListItem";
position++;
newItem.position = position;
newItem.name = curItem.text;
newItem.item = curItem.getAttribute('href');
listArray.push(newItem);
}
// Create overarching Schema object
var breadcrumbSchema = {
"@context": "https://schema.org/","@type": "BreadcrumbList","itemListElement": listArray
};
// Stringify JSON
var finalSchema = JSON.stringify(breadcrumbSchema);
// Add schema to Script
el.text = finalSchema;
// Set head variable with browser fallback
var head = document.head || document.getElementsByTagName("head")[0];
// Add to head (This won't work in codepen)
head.appendChild(el);
// Testing purposes - Show example of string in HTML
document.querySelector('.output').innerHTML = finalSchema;
// Testing purposes - Inspect source to see script generated inside of the "output" div
document.querySelector('.output').appendChild(el);
第三:你真的想这样做吗?
正如一位评论者提到的,用 JavaScript 写出 JSON-LD 可能是一个问题。如果您对此的意图与 SEO 相关,您可能希望安全投注并呈现此服务器端。无法保证搜索引擎机器人会捕捉到客户端呈现的类似内容。
更新: It looks like Google will play nicely with JSON-LD rendered dynamically,但这对于其他搜索引擎来说仍然可能是个问题。我也喜欢谨慎行事。谢谢@JayGray
如果您必须对 JSON-LD 的值进行硬编码,正如评论者提到的,您可以使用仍受支持的 RDFa(即使与 JSON-LD 相比不是首选)。根据您的代码动态呈现 HTML。以下是 BreadcrumbList on schema.org 中的示例:
<ol vocab="https://schema.org/" typeof="BreadcrumbList">
<li property="itemListElement" typeof="ListItem">
<a property="item" typeof="WebPage" href="https://example.com/dresses">
<span property="name">Dresses</span>
</a>
<meta property="position" content="1">
</li>
<li property="itemListElement" typeof="ListItem">
<a property="item" typeof="WebPage" href="https://example.com/dresses/real">
<span property="name">Real Dresses</span>
</a>
<meta property="position" content="2">
</li>
</ol>
(请记住,RDFa 和微数据 - 与 JSON-LD 不同 - 如果动态生成,将不会被搜索引擎接收)。
最后说明:
尽管建议将 JSON-LD 放在 head
中,但它不需要才能被正确提取(至少在 Google 中是这样)。它真的可以出现在您内容中的任何地方,而且也能正常工作。
- Here is an article stating it does not need to be in head。
- Here is confirmation straight from Google
此外,如果您通过 Structured Data Testing tool 运行您的页面 - 正文中的任何 JSON-LD 仍然可以正常验证。我认为 Rich Snippets tool 也会验证,但我还没有确认。
,我发现,我们并不需要的JavaScript动态填充值。 HTML5效果很好。下面是最终的脚本,我使用来呈现模式
附言业务需求是使用JSON-LD,而不是RDFa的
<script type="application/ld+json">
{
"@context": "https://schema.org/","itemListElement": [
{
"@type": "ListItem","position": 1
"name": "Home","item": "${baseURL}",},<c:forEach items="${breadcrumbArray}" var="breadcrumb" varStatus="loopCounter">
{
"@type": "ListItem","position": ${loopCounter.index+1}
"name": "${fn:replace(breadcrumb,'-',' ')}","item": "${baseURL}${breadcrumbArray[loopCounter.index-1]}/${breadcrumb}",}
</c:forEach>
]
}
</script>