【问题标题】:How to send JSON as form data using Faraday's post method如何使用法拉第的 post 方法将 JSON 作为表单数据发送
【发布时间】:2019-01-10 21:39:13
【问题描述】:

我应该如何使用带有“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


    【解决方案1】:

    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}。如果你在另一端解析数据,你可以让它工作,但它总是更难打破惯例。

    【讨论】:

      【解决方案2】:

      对于 POST 请求,Faraday 希望表单数据为 JSON 字符串,而不是 Ruby 哈希。这可以通过使用json gem's Hash#to_json 方法轻松完成,如下所示:

      require 'json'
      
      url       = 'http://localhost:8081'
      form_data = {
        name: 'John',
        age: '30',
        cars: {
          car1: 'Ford',
          car2: 'BMW',
          car3: 'Fiat'
        }
      }.to_json
      
      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)
      

      【讨论】:

        猜你喜欢
        • 2021-10-06
        • 2017-10-31
        • 1970-01-01
        • 1970-01-01
        • 2011-10-09
        • 2012-05-13
        • 1970-01-01
        • 1970-01-01
        • 2014-07-19
        相关资源
        最近更新 更多