我希望有人能为我澄清一些事情。我使用的是Rails 2.3.5,我可以在控制器操作中访问请求头,如下所示:
def index
if request.headers['...'] == '...'
...
end
end
request.headers是ActionController::Http::Headers的一个示例,它看起来是一个Hash函数,因此我希望header是以我发送的名字为键的,但是如果我发送一个请求,带有一个Authorization头,如下所示:
curl -H 'Authorization: OAuth realm="MyRealm",...' http://app/path
操作中的以下代码返回false:
if request.headers.include?('Authorization') ...
而下面的代码回应了我在头中发送的值:
render :text => request.headers['Authorization']
有趣的是,下面的检查返回true:
if request.headers.include?('HTTP_AUTHORIZATION') ...
类似地,下面的代码回显了我在标头中发送的值:
render :text => request.headers['HTTP_AUTHORIZATION']
似乎有一些我不知道的魔法在发生。我完全搞不懂为什么检查'Authorization'键失败,但是呈现request.headers ['Authorization']的值成功了。我也搞不懂'HTTP_AUTHORIZATION'是从哪里来的,因为它 * 不是 * 我和请求一起发送的头的名称。有人知道到底发生了什么吗?
2条答案
按热度按时间pdsfdshx1#
您是正确的-
ActionController::Request
的headers
方法返回ActionController::Http::Headers
的一个示例,它继承自Hash。如果我们打开源代码,我们会看到:因此,当通过
[]
访问Hash时,需要再次检查env_name
中的值是否存在(该值只是将键大写并将HTTP_
置于前面)。这就是为什么你不能从
request.headers.include?('Authorization')
中得到一个真值的原因--include?
在子类中没有被覆盖来检查头文件的普通版本和升级版本。我想你可以照做并自己实现它,如下所示:把它放到
lib/extensions/action_controller.rb
或其他东西中,如果必要的话,在environment.rb
中要求它,这样就可以了。不过,我建议修改控制器代码,使用[]
和present?
来做检查:)我相信,标头被升级并以
HTTP_
作为前缀的 * 原因 * 源于Rack,Rails的HTTP中间件。它这样做可能是为了保持大小写的公正性,另外,前置HTTP_
是为了避免与其他进入的非标头环境内容冲突。所以,是的,有点神奇,但在浏览了源代码后并不难理解,我总是推荐:)Rails有一些非常好的源代码,这些年来我从中学到了很多。
flseospp2#
根据通用网关接口RFC:
如果使用的协议是HTTP,则名称以
"HTTP_"
开头的元变量包含从客户机请求头字段中读取的值。HTTP头字段名称转换为大写,所有"-"
替换为"_"
,并在前面加上"HTTP_"
以给予元变量名称。