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

发布于 2024-12-16 14:06:57 字数 545 浏览 7 评论 0原文

例如,在 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会导致内容类型受到尊重,但显然这不是真正的解决方案。有谁知道解决这个问题的正确方法?谢谢。

For instance, in the RestClient console:

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

This does not send application/json as the content type. Instead I see:

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

I was able to trace the change to restclient/payload.rb:

  class UrlEncoded < Base
  ...

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

Replacing super.merge with super causes the content type to be respected, but obviously that's not a real solution. Does anyone know the proper way to fix this? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

虫児飞 2024-12-23 14:06:58

您可能希望将 json 作为字符串而不是哈希值作为有效负载。例如,执行以下操作:

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

如果您查看 Payload.rb,它表明如果有效负载是字符串,它将使用 Base 类而不是 UrlEncoded 类。尝试一下,看看是否适合您。

You might want to put json as string as your payload instead of hash. For example, do:

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

If you look at the payload.rb, it shows that it will use the Base clase instead of UrlEncoded class if the payload is string. Try that and see if that work for you.

饮湿 2024-12-23 14:06:58

事实

对于:post请求,当payloadHash时,Content-Type 标头将始终被覆盖为 application/x-www-form-urlencoded

可使用 Rest-client (2.0.0) 重现。

解决方案

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

require 'json'

payload.to_json

在rest-client的仓库中有一个ticket

Fact:

For :post request, when payload is a Hash, the Content-Type header will be always overridden to application/x-www-form-urlencoded.

Reproduciable with rest-client (2.0.0).

Solution:

Convert the hash payload to json string.

require 'json'

payload.to_json

There is a ticket in rest-client's repo:

葬花如无物 2024-12-23 14:06:58

我想补充一点,我的问题是使用 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"}'
)

I'd like to add that my issue was when using RestClient::Request.execute (as opposed to RestClient.post or RestClient.get).

The problem was with how I was setting :content_type and :accept. From the examples I saw it felt like they should be top level options like this:

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

But you actually have to put them within :headers like this:

res = RestClient::Request.execute(
  :method => :get,
  :url => url,
  :verify_ssl =>  false,
  :headers => { 
    :Authorization => "Bearer #{token}", 
    :content_type => :json,
    :accept => :json
  },
  :payload => '{"a":"b"}'
)
赢得她心 2024-12-23 14:06:58

我试图通过 POST 以表单数据格式提交用户名和密码以及 csrf 令牌和身份验证 cookie。有效负载转换为 json 并显式设置内容类型标头没有帮助。我最终将有效负载作为查询字符串传递,并删除了其对 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 正文中传递查询字符串仍然是一个可行的选择。希望这可以帮助某人。

I was trying to submit username and password, alongside csrf tokens and auth cookie, via POST in form data format. Payload conversion to json and explicitly setting content-type header did not help. I ended up passing payload as a query string and removed its conversion to 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}
)

Another option would also be to use encode_www_form, but a query string works better for my specific use case.

While this is not a common case and all depends on parameter format expected by the back end, it's still a viable option to pass a query string in the POST body if the server expects url encoding as POST body. Hopefully this might help someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文