我有以下Sinatra代码:
post '/bucket' do
# determine if this call is coming from filling out web form
is_html = request.content_type.to_s.downcase.eql?('application/x-www-form-urlencoded')
# If this is a curl call, then get the params differently
unless is_html
params = JSON.parse(request.env["rack.input"].read)
end
p params[:name]
end
如果我使用Curl调用此方法,params
会有值,但是当通过网络表单调用时,params
为nil
而params[:name]
则没有。我花了几个小时搞清楚它为什么会发生并向其他人寻求帮助,但没有人能真正知道发生了什么。
有一点需要注意的是,如果我注释掉这一行:
params = JSON.parse(request.env["rack.input"].read)
然后params
具有“网络表单”发布的正确值。
实际上,如果CURL调用调用此代码,目标是获取params
值,因此我使用了:
params = JSON.parse(request.env["rack.input"].read)
但它搞砸了网络形式的帖子。谁能解开这个谜团?
答案 0 :(得分:2)
就个人而言,我会通过在表单中设置隐藏值来做不同的事情,例如:
<input type="hidden" name="webform" value="true">
然后使用它:
if (params['webform'])
# this is a request from the form
else
# this is a request from Curl
end
如果您看到它,您就知道该请求来自您的网络表单。如果params['webform']
不存在则不是来自Curl。
我把它保存到一个文件中并用Ruby运行它:
require 'sinatra'
get '/bucket' do
params[:name]
end
使用http://localhost:4567/bucket?name=foo
调用正在运行的脚本显示:
foo
在浏览器中。
如果我修改源代码如下:
require 'sinatra'
post '/bucket' do
params[:name]
end
重新启动它并加载一个简单的HTML文件:
<html>
<body>
<form name="form" method="post" action="http://localhost:4567/bucket">
<input type="hidden" name="webform" value="true"></input>
<input type="input" name="name"></input>
<input type="submit"></input>
</form>
</body>
</html>
并输入foobar
并提交,我看到了:
foobar
在浏览器窗口中。
如果我将脚本更改为:
require 'sinatra'
post '/bucket' do
if (params[:webform])
'webform is set'
else
'webform is not set'
end
end
然后重新启动Sinatra并重新提交表单,我看到了:
webform is set
如果我使用Curl调用它:
curl --data "name=foo" http://127.0.0.1:4567/bucket
我在命令行上看到这个作为Curl的回复:
webform is not set
如果我将脚本更改为:
require 'sinatra'
post '/bucket' do
if (params[:webform])
'webform is set'
else
params[:name]
end
end
重新启动脚本,再次使用Curl命令调用它,我看到了:
foo
在命令行上。