Ruby 发送 JSON 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2024805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ruby send JSON request
提问by Andy
How do I send a JSON request in ruby? I have a JSON object but I dont think I can just do .send. Do I have to have javascript send the form?
如何在 ruby 中发送 JSON 请求?我有一个 JSON 对象,但我认为我做不到.send。我必须让 javascript 发送表单吗?
Or can I use the net/http class in ruby?
或者我可以在 ruby 中使用 net/http 类吗?
With header - content type = json and body the json object?
使用 header - content type = json 和 body json 对象?
回答by CarelZA
uri = URI('https://myapp.com/api/v1/resource')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.body = {param1: 'some value', param2: 'some other value'}.to_json
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(req)
end
回答by neoneye
require 'net/http'
require 'json'
def create_agent
uri = URI('http://api.nsa.gov:1337/agent')
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
req.body = {name: 'John Doe', role: 'agent'}.to_json
res = http.request(req)
puts "response #{res.body}"
rescue => e
puts "failed #{e}"
end
回答by Brian Armstrong
HTTPartymakes this a bit easier I think (and works with nested json etc, which didn't seem to work in other examples I've seen.
我认为HTTParty使这更容易一些(并且适用于嵌套的 json 等,这在我见过的其他示例中似乎不起作用。
require 'httparty'
HTTParty.post("http://localhost:3000/api/v1/users", body: {user: {email: '[email protected]', password: 'secret'}}).body
回答by equivalent8
real life example, notify Airbrake API about new deploymentvia NetHttps
现实生活中的例子,通过 NetHttps通知Airbrake API 新部署
require 'uri'
require 'net/https'
require 'json'
class MakeHttpsRequest
def call(url, hash_json)
uri = URI.parse(url)
req = Net::HTTP::Post.new(uri.to_s)
req.body = hash_json.to_json
req['Content-Type'] = 'application/json'
# ... set more request headers
response = https(uri).request(req)
response.body
end
private
def https(uri)
Net::HTTP.new(uri.host, uri.port).tap do |http|
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
end
end
project_id = 'yyyyyy'
project_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
url = "https://airbrake.io/api/v4/projects/#{project_id}/deploys?key=#{project_key}"
body_hash = {
"environment":"production",
"username":"tomas",
"repository":"https://github.com/equivalent/scrapbook2",
"revision":"live-20160905_0001",
"version":"v2.0"
}
puts MakeHttpsRequest.new.call(url, body_hash)
Notes:
笔记:
in case you doing authentication via Authorisation header set header req['Authorization'] = "Token xxxxxxxxxxxx"or http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
如果您通过 Authorization header set headerreq['Authorization'] = "Token xxxxxxxxxxxx"或http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html进行身份验证
回答by bbozo
It's 2020 - nobody should be using Net::HTTPany more and all answers seem to be saying so, use a more high level gem such as Faraday- Github
现在是 2020 年 - 没有人应该再使用它Net::HTTP了,所有的答案似乎都这么说,使用更高级的 gem,例如 Faraday- Github
That said, what I like to do is a wrapper around the HTTP api call,something that's called like
也就是说,我喜欢做的是围绕 HTTP api 调用的包装器,它被称为
rv = Transporter::FaradayHttp[url, options]
rv = Transporter::FaradayHttp[url, options]
because this allows me to fake HTTP calls without additional dependencies, ie:
因为这允许我在没有额外依赖的情况下伪造 HTTP 调用,即:
if InfoSig.env?(:test) && !(url.to_s =~ /localhost/)
response_body = FakerForTests[url: url, options: options]
else
conn = Faraday::Connection.new url, connection_options
Where the faker looks something like this
伪造者看起来像这样的地方
I know there are HTTP mocking/stubbing frameworks, but at least when I researched last time they didn't allow me to validate requests efficiently and they were just for HTTP, not for example for raw TCP exchanges, this system allows me to have a unified framework for all API communication.
我知道有 HTTP 模拟/存根框架,但至少当我上次研究时,它们不允许我有效地验证请求,而且它们只是用于 HTTP,而不是用于原始 TCP 交换,这个系统允许我有一个所有 API 通信的统一框架。
Assuming you just want to quick&dirty convert a hash to json, send the json to a remote host to test an API and parse response to ruby this is probably fastest way without involving additional gems:
假设您只想快速将哈希转换为 json,将 json 发送到远程主机以测试 API 并解析对 ruby 的响应,这可能是不涉及额外 gem 的最快方法:
JSON.load `curl -H 'Content-Type:application/json' -H 'Accept:application/json' -X POST localhost:3000/simple_api -d '#{message.to_json}'`
Hopefully this goes without saying, but don't use this in production.
希望这是不言而喻的,但不要在生产中使用它。
回答by Christoffer
A simple json POST request example for those that need it even simpler than what Tom is linking to:
对于那些需要它的人来说,一个简单的 json POST 请求示例甚至比 Tom 链接的更简单:
require 'net/http'
uri = URI.parse("http://www.example.com/search.json")
response = Net::HTTP.post_form(uri, {"search" => "Berlin"})
回答by tokhi
I like this light weight http request client called `unirest'
我喜欢这个名为“unirest”的轻量级 http 请求客户端
gem install unirest
gem install unirest
usage:
用法:
response = Unirest.post "http://httpbin.org/post",
headers:{ "Accept" => "application/json" },
parameters:{ :age => 23, :foo => "bar" }
response.code # Status code
response.headers # Response headers
response.body # Parsed body
response.raw_body # Unparsed body
回答by szabcsee
This works on ruby 2.4 HTTPS Post with JSON object and the response body written out.
这适用于带有 JSON 对象和写出的响应正文的 ruby 2.4 HTTPS Post。
require 'net/http' #net/https does not have to be required anymore
require 'json'
require 'uri'
uri = URI('https://your.secure-url.com')
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
request.body = {parameter: 'value'}.to_json
response = http.request request # Net::HTTPResponse object
puts "response #{response.body}"
end
回答by Moriarty
The net/http api can be tough to use.
net/http api 可能很难使用。
require "net/http"
uri = URI.parse(uri)
Net::HTTP.new(uri.host, uri.port).start do |client|
request = Net::HTTP::Post.new(uri.path)
request.body = "{}"
request["Content-Type"] = "application/json"
client.request(request)
end
回答by phil pirozhkov
data = {a: {b: [1, 2]}}.to_json
uri = URI 'https://myapp.com/api/v1/resource'
https = Net::HTTP.new uri.host, uri.port
https.use_ssl = true
https.post2 uri.path, data, 'Content-Type' => 'application/json'

