Magnolia开启缓存过滤器时范围请求返回Content-Length:0致Facebook分享失效
我来帮你搞定这个Magnolia缓存和Range请求的问题,顺便解决Facebook爬虫识别不了OG标签的麻烦~
首先咱们先理清楚核心问题:
- 在Magnolia 5.7.1中,开启缓存过滤器时,发送带
Range: bytes=0-2000的HTTP请求,返回的响应里Content-Length居然是0,哪怕状态码是正确的206 Partial Content,Content-Range也显示了正确的片段范围。 - 一旦禁用缓存模块(把
/server/filters/cache的enabled设为false),Range请求就能正常返回Content-Length:2001,完全符合预期。
而Facebook爬虫没法识别你的Open Graph标签,根源就在这里——Facebook的爬虫会发送这类Range请求来抓取页面内容,异常的Content-Length:0让爬虫拿不到有效内容,自然解析不了OG标签,哪怕你的标签配置完全正确(能通过opengraphcheck和Twitter Card Validator验证)。
这个问题本质是Magnolia 5.7.1的缓存过滤器没有正确处理带Range头的压缩内容请求:缓存模块在处理gzip压缩后的响应片段时,没有正确计算并设置对应的Content-Length值,直接返回了0。
这里给你三个不同层级的解决方案,按需选择:
1. 应急方案:临时禁用缓存过滤器
这是你已经验证有效的方法,适合紧急恢复Facebook爬虫的识别功能:
- 登录Magnolia AdminCentral,找到
/server/filters/cache配置节点 - 把
enabled属性改成false - 保存配置后重启实例就行
不过这个方法会丢掉缓存带来的性能优化,只能临时用,不建议长期保持。
2. 平衡方案:让Range请求绕过缓存
既能保留缓存对普通请求的性能提升,又能让Range请求正常处理,只需要给缓存过滤器加个排除规则:
- 打开
/server/filters/cache配置节点 - 添加一个排除规则:
- 新建子节点
excludeRequestHeaders,类型设为String,值填Range - 或者更灵活一点,加个
condition节点,用Groovy脚本判断:!request.getHeader("Range")
- 新建子节点
- 保存配置,不需要重启就能生效
这样一来,带Range头的请求会直接跳过缓存,走正常的响应流程,普通请求依然享受缓存加速。
3. 根治方案:升级Magnolia版本
这个问题在Magnolia 5.7.5及后续的维护版本里已经被官方修复了——开发团队优化了缓存过滤器处理Range请求的逻辑,现在能正确计算压缩后内容片段的Content-Length。如果你的项目允许升级,建议直接更到最新的5.7.x维护版,或者考虑升级到6.x系列(记得提前检查插件和自定义代码的兼容性)。
改完配置后,用curl再测一遍:
curl -I -X GET \ http://localhost:8080/ \ -H 'Accept-Encoding: gzip, deflate' \ -H 'Cache-Control: no-cache' \ -H 'Range: bytes=0-2000'
确认响应里的Content-Length不再是0,状态码还是206。之后再用Facebook的调试工具验证OG标签,应该就能正常识别了。
内容的提问来源于stack exchange,提问作者puhlerblet

