【问题标题】:Faraday Connection: Switching the request mode?法拉第连接:切换请求模式?
【发布时间】:2016-03-02 03:37:27
【问题描述】:

我正在使用faraday 处理对内部 API 的一些请求。 API 端点使用 CSRF 令牌,所以我也使用 faraday-cookie_jar

对于几个 API 端点,它们需要 :multipart 请求。其他人没有。

问题

有没有什么方法可以使用相同的Connection 对象,但是切换你是在做:multipart 还是:url_encoded 请求?

目前,我必须使用两个连接,具体取决于我提出的请求类型。在连接完成至少 1 个请求后,您似乎无法更改连接的请求方法。

@connection = Faraday.new(url: 'http://localhost:3000') do |faraday|
  faraday.request :url_encoded
  faraday.use :cookie_jar
  faraday.adapter Faraday.default_adapter
end

@connection.get '/something'

# try to change to :multipart
@connection.request :multipart # => Faraday::RackBuilder::StackLocked: can't modify middleware stack after making a request

它似乎不允许您在提出请求后切换。我知道您可以通过传递一个块来为每个请求本身修改一下请求,但我似乎找不到在哪里修改以切换到其中的:multipart

提前致谢。

【问题讨论】:

    标签: ruby faraday


    【解决方案1】:

    您需要在创建连接时包含两个中间件选项(:url_encoded:multipart),然后使用显式 Content-Type 标头进行切换。

    根据Faraday ReadMe,您可以同时指定它们。摘录:

     Faraday.new(...) do |conn|
        # POST/PUT params encoders:
        conn.request :multipart
        conn.request :url_encoded
        conn.adapter :net_http
      end
    

    此请求中间件设置通过以下方式影响 POST/PUT 请求:

    1. Request::Multipart 检查负载中的文件,否则保持一切不变;
    2. Request::UrlEncoded 如果尚未编码或其他类型,则编码为“application/x-www-form-urlencoded”。

    所以添加 :multipart 仍然允许使用 url 编码的帖子,因为它仅在有效负载中有文件时才重要。然后,如果您为文件上传明确设置Content-Type,您应该没问题 - Faraday 将使用正确的请求中间件,因为您明确告诉它使用 multipart。但如果你指定,它将默认为 url-encoded。

    # works using :url_encoded
    @connection.post '/something' do |req|
      req.body = { some: 'posted fields' }
    end
    
    # works using :multipart because Content-Type was explicitly set
    @connection.post '/some_file_endpoint' do |req|
      req.headers['Content-Type'] = 'multipart/form-data'
      req.body = { file_field: Faraday::UploadIO.new(file_path, 'text/plain') }
    end
    

    【讨论】:

      【解决方案2】:

      调用@connection.request :multipart 会将Faraday::Request::Multipart 添加到@connecton.builder.handlers。如果你想删除一些东西,你可以操作那个数组。

      我没有声称弄乱法拉第的(相对)内部是一个好主意。保持两个连接听起来是一个更好的计划。

      【讨论】:

        【解决方案3】:

        Sean 的回答听起来是正确的做法,但如果您确实想修改您的连接,您必须先复制它:

        @connection = @connection.dup
        @connection.request :multipart
        

        这也可用于从连接中删除中间件:

        @connection = @connection.dup
        @connection.builder.delete(Faraday::Request::lookup_middleware(:multipart))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-08
          • 1970-01-01
          相关资源
          最近更新 更多