【问题标题】:Is there a way to send JSON with DELETE request with Net::HTTP?有没有办法使用 Net::HTTP 发送带有 DELETE 请求的 JSON?
【发布时间】:2023-03-08 23:40:01
【问题描述】:

我在 Sinatra 应用程序中使用 Net::HTTP 进行 CRUD 请求。对于删除请求,我需要随请求一起发送 JSON:

uri = URI.parse('http://localhost:3000')    
http = Net::HTTP.new(uri.host, uri.port)
path = '/resource/resource-id'
request = Net::HTTP::Delete.new(path)
request.basic_auth('username', 'password')

response = http.request(request)

上面的代码发送DELETE请求就好了,但是当我发送JSON时,

request = Net::HTTP::Delete.new(path, '{"ids": ["abc123"]}')
request.basic_auth('username', 'password')

response = http.request(request)

它抛出:

'400 Invalid URI'    

我经常使用 HTTParty gem,我知道它可以达到这个目的,但我不想只为一个 API 包含一个 gem。

非常感谢任何帮助/指针。

更新 正如@kimball 和@Zoker 所建议的,这就是我所做的(我使用的是ruby-2.0.0-p643 MRI):

request = Net::HTTP::Delete.new(path, {'Depth' => 'Infinity', 
                                       'Content-Type' =>'application/json'})
request.body = '{"ids":["abc123"]}'
request.basic_auth('username', 'password')

response = http.request(request)

它抛出:

'400 Invalid URI'    

更新 2 再次按照 cmets 中的建议:

require 'json'
request.body = {"ids" => ["abc123"]}.to_json

结果还是一样。

response = http.request(request)
=> #<Net::HTTPBadRequest 400 Invalid URI readbody=true>

【问题讨论】:

  • 我无法复制您的错误 - 前面的行 request = Net::HTTP::Delete.new(path, '{"ids": ["abc123"]}') 引发了另一个错误。第二个参数不应该是标题的哈希吗?你想把你的 JSON - header/body/form 数据放在哪里?
  • 谢谢@Kimball 我已经更新了我的问题,为标题添加哈希仍然会引发 400 错误
  • 为了完整起见,您可以尝试Net::HTTPHeader#set_form_data,但 IIRC 它只是将哈希转换为查询参数。如果可能的话,也不要编写自己的 JSON,require 'json' 可能更不容易出错并使用Hash#to_json。在不知道您尝试与之交互的服务的情况下,我无法提供太多建议;重载 DELETE 请求是一项艰巨的任务!
  • 关于 Hash#to_json 的好点,在代码中我也在做同样的事情。
  • 我已经在可用信息(不了解服务器)上尽可能合理地对此进行了测试,但我无法重现您的错误。我自己处理外部服务的经验主要是糟糕的文档——我经常把我的参数放在我能做的任何地方(标题、正文、查询参数),直到我找到有用的东西。如果是内部的,至少你可以检查自己的服务器代码。

标签: ruby json net-http


【解决方案1】:

Net::HTTP::Delete.new() 方法在标头中提供传递参数

# File lib/net/http.rb, line 1231
def delete(path, initheader = {'Depth' => 'Infinity'})
  request(Delete.new(path, initheader))
end
# via: http://docs.ruby-lang.org/en/2.1.0/Net/HTTP.html

你可以这样使用:

Net::HTTP::Delete.new(path,{'Depth' => 'Infinity', 'foo' => 'bar'})

Delete.new(path,params) 中的参数是散列,而不是字符串。

更重要的是,哈希值必须是String

[更新]

我们可以像这样将 json 字符串放入 request.body 中

require 'json'

request.body = JSON.generate({'foo'=>'bar','key'=>'value'})

或者你可以自己生成json字符串

request.body = "{\"foo\":\"bar\",\"key\":\"value\"}"

【讨论】:

  • 虽然这给了我指针,你能解释一下我如何发送 JSON 请求吗?作为标题还是正文?
  • @gouravtiwari21 我已经更新了我的答案,您可以将 json 字符串传递给 request.body ,您需要做的只是确保 json 字符串格式正确。
  • 哎呀,但它对我有用,我从响应正文中得到 {"foo":"bar","key":"value"}
  • 这可能是因为您使用的是最新的 ruby​​(2.1 或 2.2)?我被这个项目困住了 ruby​​ 2,0
【解决方案2】:

您也可以在您的请求中添加 if/elsif 语句并应用:

elsif delete
    request = Net::HTTP::Delete.new(path)
end

path 是你指定的 URL

【讨论】:

    猜你喜欢
    • 2010-10-06
    • 2016-07-18
    • 1970-01-01
    • 2019-02-20
    • 2013-01-16
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多