0

我有以下 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它有值,但是当它通过 Web 表单调用时,它paramsnil并且params[:name]什么都没有。我花了几个小时弄清楚为什么会发生这种情况并寻求其他人的帮助,但没有人能真正找出发生了什么。

需要注意的一件事是,如果我注释掉这一行:

params = JSON.parse(request.env["rack.input"].read)

然后params具有“网络表单”发布的正确值。

params实际上,如果此代码被 CURL 调用调用,目标是获取值,所以我使用了:

params = JSON.parse(request.env["rack.input"].read)

但它搞砸了网络表单的发布。谁能解开这个谜?

4

1 回答 1

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

在命令行上。

于 2012-12-10T23:07:27.817 回答