使用cURL命令行未完全接收Rails参数

时间:2015-09-15 15:14:40

标签: ruby-on-rails curl

我是Rails的新手,在编写Rails API时遇到了一个奇怪的问题。

我的控制器如下所示:

class Api::PipelineController < ApplicationController
   before_action :query_params

  def index
    job_id  = params[:job_id].to_i
    build_num = params[:build_num].to_i
    ...
    @result= {"foo"=>"bar"}
    ...

    respond_to do |format|
      format.json { render json: @result }
    end
  end

  private
  def query_params
    params.except('controller', 'format', 'action').permit(:job_id, :build_num)
  end
 end

我的请求API看起来像这样:

http://127.0.0.1:3456/api/pipeline?job_id=16&build_num=23

奇怪的是当我从像POSTMAN这样的GUI工具请求这个API时,它工作正常,后端rails日志看起来像这样:

Started GET "/api/pipeline?job_id=16&build_num=23" for 127.0.0.1 at 2015-09-15 23:07:27 +0800
Processing by Api::PipelineController#index as JSON
Parameters: {"job_id"=>"16", "build_num"=>"23"}

但是如果我从 cURL 请求,第二个参数build_num丢失了,那么看起来铁路输了这个参数。

curl http://127.0.0.1:3456/api/pipeline?job_id=16&build_num=23

rails后端日志看起来像这样:

Started GET "/api/pipeline?job_id=16" for 127.0.0.1 at 2015-09-15 23:12:30 +0800
Processing by Api::PipelineController#index as JSON
Parameters: {"job_id"=>"16"}

我搜索谷歌但没有运气。任何人都可以提供一些建议,我们将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:4)

问题是你的shell将&识别为在后台运行命令的指令。例如,看看这两个输出:

$ (sleep 3 && echo Awake); echo Finished
Awake
Finished
$ (sleep 3 && echo Awake) & echo Finished
[1] 23699
Finished
Awake

第二个命令在后台运行sleep 3 && echo Awake,允许在Finished完成之前打印sleep23699是已经背景的进程ID,以防您需要发送信号。

所以当你运行

curl http://127.0.0.1:3456/api/pipeline?job_id=16&build_num=23

你实际上正在运行

curl http://127.0.0.1:3456/api/pipeline?job_id=16 &
build_num=23

在很多情况下,shell会报告command not found错误,但您也碰巧偶然发现了变量设置,如果现在是echo $build_num,那么您的shell会打印23 }。

结果是,只要您使用带有参数的网址的cURL,请将URL包装在引号中。单引号是最安全的,因为shell不会在其中进行任何变量评估等(例如echo "number is $build_num"打印number is 23,而echo 'number is $build_num'打印number is $build_num),但只要在shell中识别为特殊的$`等内容中没有任何内容,双引号就可以了。

答案 1 :(得分:2)

用双引号括起请求网址:

curl "http://127.0.0.1:3456/api/pipeline?job_id=16&build_num=23"

因为shell正在干扰&amp;字符。来自curl docs

  

在从命令行提示符调用时使用[]或{}序列时,您可能必须将完整的URL放在双引号内以避免shell干扰它。这也适用于其他特殊处理的角色,例如&#39;&amp;&#39;,&#39;?&#39;和&#39; *&#39;。