如何使用 Faraday 的 post 方法发送 JSON 作为表单数据

问题描述 投票:0回答:2

我应该如何使用带有“application/x-www-form-urlencoded”和“multipart/form-data;”的 post 方法在 Faraday 中发送此 JSON标题?

message = {
  "name":"John",
  "age":30,
  "cars": {
    "car1":"Ford",
    "car2":"BMW",
    "car3":"Fiat"
  }
 }

我已经尝试过:

conn = Faraday.new(url: "http://localhost:8081") do |f|
  f.request :multipart
  f.request :url_encoded
  f.adapter :net_http
end

conn.post("/", message)

这个 cURL 请求有效

curl -X POST \
  http://localhost:8081 \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F 'message=2018-12-27 12:52' \
  -F source=RDW \
  -F object_type=Responses

但我不太知道如何让它在法拉第工作。此外,cURL 请求中的数据不是嵌套的 JSON,因此我需要能够动态创建请求正文,因为我不会提前知道 JSON 的确切结构。

如果您需要更多详细信息或清晰度,请提出任何问题。

谢谢!

json multipartform-data url-encoding faraday
2个回答
6
投票

POST 的默认内容类型是

x-www-form-urlencoded
,因此将自动编码哈希值。 JSON 没有这样的自动数据处理,这就是为什么下面的第二个示例传递哈希的字符串化表示形式。

Faraday.new(url: 'http://localhost:8081').post('/endpoint', {foo: 1, bar: 2})
# => POST http://localhost:8081/endpoint
#         with body 'bar=2&foo=1'
#         including header 'Content-Type'=>'application/x-www-form-urlencoded'

Faraday.new(url: 'http://localhost:8081').post('/endpoint', {foo: 1, bar: 2}.to_json, {'Content-Type'=>'application/json'})
# => POST http://localhost:8081/endpoint
#         with body '{"foo":1,"bar":2}'
#         including header 'Content-Type'=>'application/json'

我不确定您打算做什么,但您可以发送如下内容

Faraday.new(url: 'http://localhost:8081').post('/endpoint', {foo: 1, bar: 2}.to_json)
# => POST http://localhost:8081/endpoint
#         with body '{"foo":1,"bar":2}'
#         including header 'Content-Type'=>'application/x-www-form-urlencoded'

但是,这在 Ruby 中会被解释为

{"{\"foo\":1,\"bar\":2}" => nil}
。如果您在另一端解析数据,您可以使其工作,但打破惯例总是更难。


3
投票

对于 POST 请求,Faraday 希望表单数据为 JSON string,而不是 Ruby 哈希。这可以通过使用 json gem 的

Hash#to_json
方法轻松完成,如下所示:

require 'json'

message = {
            name: 'John',
            age: '30',
            cars: {
              car1: 'Ford',
              car2: 'BMW',
              car3: 'Fiat'
            }
          }
form_data = message.to_json

url     = 'http://localhost:8081'
headers = {} 

Faraday.post(url, form_data, headers)

或者在你的例子中只是简单地:

conn = Faraday.new(url: "http://localhost:8081") do |f|
  f.request :multipart
  f.request :url_encoded
  f.adapter :net_http
end

# exact same code, except just need to call require json and call to_json here
require 'json'
conn.post("/", message.to_json)
© www.soinside.com 2019 - 2024. All rights reserved.