Ruby使用HTTP gem发送POST请求失败,CURL可正常执行
问题:CURL可正常运行的POST请求在Ruby HTTP gem中失效
问题详情
需要发送一条HTTP POST请求,该请求通过CURL可正常获取响应,但用Ruby的HTTP gem实现时始终失败。
可正常运行的CURL命令
curl https://api.kite.trade/session/token \ -H "X-Kite-Version: 3" \ -d "api_key=XXX" \ -d "request_token=XXX" \ -d "checksum=XXX"
失败的Ruby HTTP gem代码
response = http.headers("X-Kite-Version"=>"3").post( "https://api.kite.trade/session/token", body: ("api_key=" + @api_key +"\n\r" "request_token=" + @request_token +"\n\r" "checksum=" + checksum_hash.to_s) )
已尝试的无效方案
- 使用
"\n"、"\n\r"等不同换行符分隔参数 - 给body内容添加
.html_safe标记 - 构造参数数组
params = [["api_key","XXX"],["request_token","XXX"],["checksum","XXX"]]并URI编码后传入body
错误响应
{"status":"error","message":"
api_keyshould be minimum 6 characters in length.","data":null,"error_type":"InputException"}
推测是数据传递格式不符合服务器API要求,且无法修改服务器逻辑。
解决方案
问题出在请求body的格式上:curl的-d参数默认会将数据编码为application/x-www-form-urlencoded格式(参数用&分隔),而你之前用换行分隔参数,服务器无法正确解析。
方法1:使用HTTP gem的表单参数自动处理
直接传递哈希给:form参数,HTTP gem会自动编码并设置正确的Content-Type:
response = http.headers("X-Kite-Version" => "3").post( "https://api.kite.trade/session/token", form: { api_key: @api_key, request_token: @request_token, checksum: checksum_hash.to_s } )
方法2:手动构造符合要求的body
如果需要手动构造body,需用&分隔参数,并确保参数经过URL编码,同时指定Content-Type:
require 'uri' body = URI.encode_www_form({ api_key: @api_key, request_token: @request_token, checksum: checksum_hash.to_s }) response = http.headers({ "X-Kite-Version" => "3", "Content-Type" => "application/x-www-form-urlencoded" }).post( "https://api.kite.trade/session/token", body: body )
内容的提问来源于stack exchange,提问作者Sudipta Mondal
相关产品推荐
相关产品推荐

