我是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"}
我搜索谷歌但没有运气。任何人都可以提供一些建议,我们将不胜感激,谢谢。
答案 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
完成之前打印sleep
。 23699
是已经背景的进程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;。