Pat*_*ien 7 ruby upload http mechanize multipart
我只是想用POST将图像上传到服务器.就像这个任务听起来那么简单,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.closeRun Code Online (Sandbox Code Playgroud)
这导致服务器上完全垃圾就绪的文件看起来遍布:
我的下一步是将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.closeRun Code Online (Sandbox Code Playgroud)
我正在使用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中的文件上传到多部分表单?
问题很严重,答案很简单:我在Windows下缺少读取图像的二进制模式.
f = File.new(filename, File::RDWR)
必须是
f = File.new(filename, "rb")