我想要使用POST方法将图片上传到服务器。虽然这个任务听起来很简单,但在Ruby中似乎没有简单的解决方案。
在我的应用程序中,我大多数情况下都使用WWW::Mechanize,所以我也想在这里使用它,并有以下源代码:
这导致服务器上的文件完全无法使用,看起来乱七八糟:
下一个想法是使用不同的 gem,所以我尝试使用 Net::HTTP。经过简短的调查,我发现 Net::HTTP 没有原生支持多部分表单,而是必须构建一个类来为您进行编码等操作。我能找到的最有帮助的是 Stanislav Vitvitskiy 的 Multipart-class。这个类目前看起来很好,但它不能做我需要的事情,因为我不仅想要发布文件,还想发布普通数据,而这在他的类中是不可能的。
我正在使用 http://rest-test.heroku.com,它会在请求正确发送时将其发送回来以进行调试,但我总是收到以下响应:
如何在Ruby中上传文件到多部分表单而不必自己实现整个编码和数据对齐过程?
在我的应用程序中,我大多数情况下都使用WWW::Mechanize,所以我也想在这里使用它,并有以下源代码:
f = File.new(filename, File::RDWR)
reply = agent.post(
'http://rest-test.heroku.com',
{
:pict => f,
:function => 'picture2',
:username => @username,
:password => @password,
:pict_to => 0,
:pict_type => 0
}
)
f.close
这导致服务器上的文件完全无法使用,看起来乱七八糟:
我的下一步是将WWW::Mechanize降级到版本0.8.5。这个方法有效,直到我尝试运行它时出现了错误,像“在hpricot_scan.so中找不到模块”。使用Dependency Walker工具,我发现hpricot_scan.so需要msvcrt-ruby18.dll。然而,即使我将该.dll放入Ruby/bin文件夹中,它也会给我一个空的错误框,从那里我无法进一步调试。所以问题在于,Mechanize 0.8.5依赖于Hpricot而不是Nokogiri(后者运行得非常流畅)。
下一个想法是使用不同的 gem,所以我尝试使用 Net::HTTP。经过简短的调查,我发现 Net::HTTP 没有原生支持多部分表单,而是必须构建一个类来为您进行编码等操作。我能找到的最有帮助的是 Stanislav Vitvitskiy 的 Multipart-class。这个类目前看起来很好,但它不能做我需要的事情,因为我不仅想要发布文件,还想发布普通数据,而这在他的类中是不可能的。
我的最后一次尝试是使用RestClient。这看起来很有前途,因为有上传文件的示例。但我无法将其作为多部分表单进行发布。
f = File.new(filename, File::RDWR)
reply = RestClient.post(
'http://rest-test.heroku.com',
:pict => f,
:function => 'picture2',
:username => @username,
:password => @password,
:pict_to => 0,
:pict_type => 0
)
f.close
我正在使用 http://rest-test.heroku.com,它会在请求正确发送时将其发送回来以进行调试,但我总是收到以下响应:
POST http://rest-test.heroku.com/ with a 101 byte payload, content type application/x-www-form-urlencoded { "pict" => "#<File:0x30d30c4>", "username" => "s1kx", "pict_to" => "0", "function" => "picture2", "pict_type" => "0", "password" => "password" }这清楚地表明它不使用
multipart/form-data
作为内容类型,而是使用标准的 application/x-www-form-urlencoded
,尽管它确实看到 pict
是一个文件。
如何在Ruby中上传文件到多部分表单而不必自己实现整个编码和数据对齐过程?