法拉第连接:切换请求模式?

Lev*_*evi 6 ruby faraday

我用来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
Run Code Online (Sandbox Code Playgroud)

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

提前致谢。

Sea*_*ean 2

您需要在创建连接时包含两个: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
Run Code Online (Sandbox Code Playgroud)

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

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

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

# 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
Run Code Online (Sandbox Code Playgroud)