假设你有一个网址
localhost:3000?a=1
并且在请求中,您还有一个post参数
a=2
会是什么
在这种情况下, params[:a]
? 是否依赖于HTTP动词?
如果它取决于HTTP动词,
如果您的表单看起来像
<form method='post' action='/?a=2'>
<input type='hidden' name='a' value='3'/>
</form>
在这种情况下params[:a]
会是什么?
更新
所以我只做了一个小实验并使用Chrome调试器追加?authenticity_token=abc
操作网址。我查看了服务器日志,发现参数有authenticity_token => 'abc'
。我也相信在这种情况下该方法是POST
。
让我知道你们想出了什么。
答案 0 :(得分:20)
当我在示例代码中尝试这个时,我能够看到的是查询参数(GET)优先于POST主体。所以,我开始研究处理Rails中HTTP请求的Rack
代码。以下是request.rb
# Returns the data recieved in the query string.
def GET
....
end
# Returns the data recieved in the request body.
#
# This method support both application/x-www-form-urlencoded and
# multipart/form-data.
def POST
....
end
# The union of GET and POST data.
def params
@params ||= self.GET.merge(self.POST)
rescue EOFError
self.GET
end
这里,方法
因此,根据params
的代码,在相同键的情况下,POST参数应该覆盖GET参数。 (self.GET.merge(self.POST)
)。但是,这与我实际尝试时的结果相反。
因此,唯一的机会是这个代码被Rails覆盖。当我想到它时,它非常有意义,因为来自Rails的params
哈希将始终包含"controller"
和"action"
个键,如果是Rack,则不会出现这些键。所以,我也查看了Rails的代码,发现params
方法确实被覆盖了。在Rails源代码中查看request.rb和parameters.rb。在parameters.rb中,我们有:
# Returns both GET and POST \parameters in a single hash.
def parameters
@env["action_dispatch.request.parameters"] ||= begin
params = request_parameters.merge(query_parameters)
params.merge!(path_parameters)
encode_params(params).with_indifferent_access
end
end
alias :params :parameters
并在request.rb中:
# Override Rack's GET method to support indifferent access
def GET
@env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {})
end
alias :query_parameters :GET
# Override Rack's POST method to support indifferent access
def POST
@env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {})
end
alias :request_parameters :POST
所以,这里
params
的别名(此处已被覆盖)请注意,GET方法和POST方法也被重写,主要是将返回的哈希转换为HashWithIndifferentAccess的对象。
因此,查看此处的代码(params = request_parameters.merge(query_parameters)
),很明显在Rails中,如果键相同,则GET参数会覆盖POST参数。或者换句话说,GET参数优先于POST参数。
答案 1 :(得分:6)
Rails uses Rack::Request
用于HTTP请求。但是,它会重新定义Rack
中的ActionDispatch::Http::Parameters
params
方法(通过别名)。
这个返回请求参数的params
方法实现为:
# Returns both GET and POST \parameters in a single hash.
def parameters
@env["action_dispatch.request.parameters"] ||= begin
params = request_parameters.merge(query_parameters)
params.merge!(path_parameters)
encode_params(params).with_indifferent_access
end
end
alias :params :parameters
请注意别名parameters
方法。
除非重新定义,否则查询字符串中的参数将覆盖POST正文中的参数。
答案 2 :(得分:1)
它将是2.但是对于路由,它将与'1'匹配。
如果需要,可以使用request.GET和request.POST访问get和post vars。
答案 3 :(得分:1)
不,它不依赖于de HTTP动词,但你确定可以有不同的动作来处理GET
和POST
,或者它可以是相同的,你会得到`params [:a]在这两种情况下。