如何让Ruby的RestClient gem在帖子上尊重content_type?

时间:2011-11-18 22:26:04

标签: ruby rest-client

例如,在RestClient控制台中:

RestClient.post 'http://localhost:5001', {:a => 'b'}, :content_type => 'application/json'

这不会将application / json作为内容类型发送。相反,我看到了:

Content-Type: application/x-www-form-urlencoded

我能够跟踪对restclient / payload.rb的更改:

  class UrlEncoded < Base
  ...

  def headers
    super.merge({'Content-Type' => 'application/x-www-form-urlencoded'})
  end
end

用super替换super.merge导致内容类型得到尊重,但显然这不是一个真正的解决方案。有谁知道解决这个问题的正确方法?感谢。

4 个答案:

答案 0 :(得分:22)

您可能希望将json作为字符串作为有效负载而不是散列。例如,执行:

RestClient.post 'http://localhost:5001','{"a":"b"}',:content_type => 'application/json'

如果查看payload.rb,它表明如果有效负载是字符串,它将使用Base clase而不是UrlEncoded类。试试看,看看那对你有用。

答案 1 :(得分:9)

<强>事实

对于EmbeddedJar请求,当:postpayload时,Hash标题将始终被覆盖为Content-Type

可以通过rest-client(2.0.0)重现。

<强>解决方案

将哈希有效负载转换为json字符串。

application/x-www-form-urlencoded

rest-client的repo中有一个ticket

答案 2 :(得分:7)

我想补充一点,我的问题是在使用RestClient::Request.execute时(而不是RestClient.postRestClient.get)。

问题在于我如何设置:content_type:accept。从我看到的例子中我觉得它们应该是这样的顶级选项:

res = RestClient::Request.execute(
  :method => :get,
  :url => url,
  :verify_ssl =>  false,
  :content_type => :json,
  :accept => :json,
  :headers => { 
    :Authorization => "Bearer #{token}", 
  },
  :payload => '{"a":"b"}'
)

但实际上你必须将它们放在:headers之内:

res = RestClient::Request.execute(
  :method => :get,
  :url => url,
  :verify_ssl =>  false,
  :headers => { 
    :Authorization => "Bearer #{token}", 
    :content_type => :json,
    :accept => :json
  },
  :payload => '{"a":"b"}'
)

答案 3 :(得分:0)

我试图通过表单数据格式的POST提交用户名和密码,以及csrf令牌和auth cookie。将有效负载转换为json并显式设置content-type标头没有帮助。我最终将有效负载作为查询字符串传递,并删除了其对JSON的转换:

RestClient::Request.execute(
  method: :post, 
  url: 'http://app_url/login.do',
  payload: "username=username&password=password&_csrf=token",
  headers: {'X-XSRF-TOKEN' => 'token'},
  cookies: {'XSRF-TOKEN' =>  cookie_object}
)

另一种选择是使用encode_www_form,但是查询字符串在我的特定用例下效果更好。

虽然这不是常见情况,并且全部取决于后端期望的参数格式,但是如果服务器希望将url编码作为POST主体,那么在POST主体中传递查询字符串仍然是可行的选择。希望这可以对某人有所帮助。