使用 mod_rewrite / RewriteCond 规则进行内容协商
Posted
技术标签:
【中文标题】使用 mod_rewrite / RewriteCond 规则进行内容协商【英文标题】:Content negotiation using mod_rewrite / RewriteCond rules 【发布时间】:2015-04-28 23:50:50 【问题描述】:我有一个用例是在 Github 页面中托管 a set of files(具有不同序列化格式的相同 RDF 内容,例如 RDF/XML、Turtle 和 JSON-LD),并使用 a w3id URL 作为永久标识符。
此外,我想对该永久 URL 进行内容协商。如果我将文件托管在 Apache 服务器中,这将是微不足道的,但不幸的是 Github 页面不支持内容协商。所以我想看看我可以在多大程度上通过 URL 重写规则来做到这一点。
所以思路和下面类似。
GET http://w3id.org/foo -- redirect to --> http://foo.git.io/content.ttl
Accept: text/turtle
GET http://w3id.org/foo -- redirect to --> http://foo.git.io/content.jsonld
Accept: application/ld+json
目前我的规则如下所示。
Options +FollowSymLinks
RewriteEngine on
RewriteCond %HTTP_ACCEPT ^.*application/rdf\+xml.*
RewriteRule ^foaf$ http://nandana.github.io/foaf/card.rdf [R=303,L]
RewriteCond %HTTP_ACCEPT ^.*text/turtle.*
RewriteRule ^foaf$ http://nandana.github.io/foaf/card.ttl [R=303,L]
RewriteCond %HTTP_ACCEPT ^.*application/ld\+json.*
RewriteRule ^foaf$ http://nandana.github.io/foaf/card.jsonld [R=303,L]
RewriteRule ^foaf$ http://nandana.github.io/foaf/card.html [R=303,L]
虽然这适用于大多数情况,但在某些极端情况下会中断。例如,如果有一个像下面这样的接受头
Accept: application/rdf+xml;q=0.9,text/turtle
这将返回 application/rdf+xml(因为第一个规则匹配)尽管根据内容协商它应该返回 turtle。有谁知道如何改进处理这种极端情况的规则?
【问题讨论】:
类似问题:Mod-Rewrite content negotiation for mixed Accept header?(Webmasters)和Redirect depending on preferred language (Accept-Language) with .htaccess(Server Fault)。 感谢@unor 的指点!!显然没有解决方案,不是吗? 我没有找到,但我仍然希望以某种方式(没有服务器端脚本)有可能。 【参考方案1】:我认为您必须对实际文件进行 0 字节的虚拟化,例如foo.ttl
、foo.jsonld
等,并确保它们的类型用AddType
声明,然后regular content negotiation 可以为http://example.com/foo
工作。
但不是为 0 字节文件提供服务,而是为每个文件设置 RewriteRule foo.ttl
等,以便将它们重定向到“真实”位置。非常冗长,是的,但是即使对于具有 q=
和多种类型的复杂 Accept
标头,也应该可以正常工作。
【讨论】:
以上是关于使用 mod_rewrite / RewriteCond 规则进行内容协商的主要内容,如果未能解决你的问题,请参考以下文章
使用 mod_rewrite 强制 SSL/HTTPS [重复]
使用 .htaccess 和 mod_rewrite 强制 SSL/https