我正在使用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
。
提前致谢。
答案 0 :(得分:1)
在创建连接(:url_encoded
和:multipart
)时,您需要包含两个中间件选项,然后使用显式Content-Type
标头切换。< / p>
根据Faraday ReadMe,您可以指定'em'。摘录:
Faraday.new(...) do |conn| # POST/PUT params encoders: conn.request :multipart conn.request :url_encoded conn.adapter :net_http end
此请求中间件设置以下列方式影响POST / PUT请求:
Request::Multipart
检查有效负载中的文件,否则保持所有内容不受影响;- 醇>
Request::UrlEncoded
编码为“application / x-www-form-urlencoded”,如果尚未编码或其他类型。
因此,添加:multipart
仍允许使用网址编码的帖子,因为只有在有效负载中有文件时才会这样做。然后,如果您为文件上传明确设置了Content-Type
,那么您应该没问题 - 法拉第将使用正确的请求中间件,因为您明确告诉它使用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
答案 1 :(得分:0)
致电@connection.request :multipart
将Faraday::Request::Multipart
添加到@connecton.builder.handlers
。如果要删除某些内容,可以操作该数组。
我没有声称搞乱法拉第(相对)内部是一个好主意。保持你的两个联系听起来像一个更好的计划。