如何从 PHP 中的 HTTP Accept 标头选择内容类型
我正在尝试构建一个符合标准的网站框架,根据浏览器支持,将 XHTML 1.1 作为 application/xhtml+xml 或 HTML 4.01 作为 text/html 提供服务。 目前,它只是在接受标头中的任何位置查找“application/xhtml+xml”,并使用它(如果存在),但这并不灵活 - text/html 可能会有更高的分数。 此外,当添加其他格式(WAP、SVG、XForms 等)时,它会变得更加复杂。 那么,有谁知道一段经过测试的 PHP 代码可以从服务器给出的字符串数组中选择客户端最支持的一个或基于客户端分数的有序列表?
I'm trying to build a standard compliant website framework which serves XHTML 1.1 as application/xhtml+xml or HTML 4.01 as text/html depending on the browser support. Currently it just looks for "application/xhtml+xml" anywhere in the accept header, and uses that if it exists, but that's not flexible - text/html might have a higher score. Also, it will become more complex when other formats (WAP, SVG, XForms etc.) are added. So, does anyone know of a tried and tested piece of PHP code to select, from a string array given by the server, either the one best supported by the client or an ordered list based on the client score?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我的库中的小片段:
示例用法:
Little snippet from my library:
example usage:
您可以利用 apache 的 mod_negotiation 模块。 这样您就可以使用该模块提供的全方位协商功能,包括内容类型的您自己的偏好(例如,“我真的想交付 application/xhtml+xml,除非客户端非常喜欢别的东西”)。
基本解决方案:
作为内容
as 内容
为此,您需要启用 mod_negotiation,相应的未为 $_SERVER 禁用 AddHandler 和 AcceptPathInfo 的 AllowOverride 权限[ 'PATH_INFO']。
当我的 Firefox 发送“Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8”时,示例 .var 映射的结果是“selected type” :xhtml”。
您可以使用其他“调整”来摆脱 PATH_INFO 或请求 foo.var 的需要,但基本概念是:让 mod_negotiation 以脚本可以的方式将请求重定向到您的 php 脚本“读取”所选内容类型。
It's not a pure php solution but I'd say mod_negotiation has been tried and tested ;-)
You can leverage apache's mod_negotiation module. This way you can use the full range of negotiation capabilities the module offers, including your own preferences for the content type (e,g, "I really want to deliver application/xhtml+xml, unless the client very much prefers something else").
basic solution:
as contents
as contents
as contents.
For this to work you need mod_negotiation enabled, the appropriate AllowOverride privileges for AddHandler and AcceptPathInfo not being disabled for $_SERVER['PATH_INFO'].
With my Firefox sending "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8" and the example .var map the result is "selected type: xhtml".
You can use other "tweaks" to get rid of PATH_INFO or the need to request foo.var, but the basic concept is: let mod_negotiation redirect the request to your php script in a way that the script can "read" the selected content-type.
It's not a pure php solution but I'd say mod_negotiation has been tried and tested ;-)
Pear::HTTP 1.4.1 有一个方法 string NegotiMimeType( array $supported, string $default)
打印
edit: this might not be so good after all...
My firefox sends Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
text/html and application/xhtml+xml have q=1.0 but PEAR::HTTP (afaik) doesn't let you chose which one you prefer, it returns text/html no matter what you pass as $supported. This may or may not be sufficient for you. see my other answer(s).
Pear::HTTP 1.4.1 has a method string negotiateMimeType( array $supported, string $default)
prints
edit: this might not be so good after all...
My firefox sends Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
text/html and application/xhtml+xml have q=1.0 but PEAR::HTTP (afaik) doesn't let you chose which one you prefer, it returns text/html no matter what you pass as $supported. This may or may not be sufficient for you. see my other answer(s).
仅供记录,Negotiation 是一个用于处理内容协商的纯 PHP 实现。
Just for the record, Negotiation is a pure PHP implementation for dealing with content negotiation.
将 @maciej-Łebkowski 和 @chacham15 解决方案与我的问题修复和改进合并。 如果您传递
$desiredTypes = 'text/*'
且Accept
包含text/html;q=1
则text/html< /code> 将被返回。
Merged @maciej-Łebkowski and @chacham15 solutions with my issues fixes and improvements. If you pass
$desiredTypes = 'text/*'
andAccept
containstext/html;q=1
thentext/html
will be returned.PEAR 的 HTTP2 库 支持解析所有类型的
Accept
标头。 它可以通过 composer 和 PEAR 安装。示例可以在文档或我的博客文章。
PEAR's HTTP2 library supports parsing all types of
Accept
headers. It's installable via composer and PEAR.Examples can be found at the documentation or my blog post.
客户端可以接受响应中的 MIME 类型列表。 另一方面,响应的顺序对于客户端来说非常重要。 PHP Pear HTTP2 是最好的选择包括语言、字符集和 mimetypes。
这是一个很好的教程: https://cweiske.de/tagebuch/php-http-谈判.htm
Client may accept a list of mime-types in the response. In the other hand the order of the response is very important for client side. PHP Pear HTTP2 is the best to deal with language, charset, and mimetypes.
Here is a good tutorial: https://cweiske.de/tagebuch/php-http-negotiation.htm