我只是想用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.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中没有对多部分表单的本机支持,而是你必须构建一个为你编码等的类。我能找到的最有帮助的是Multipart-class by Stanislav Vitvitskiy。到目前为止,这个类看起来不错,但它不能满足我的需求,因为我不想发布仅文件,我也想发布正常的数据,这对他的班级是不可能的
我的最后一次尝试是使用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中的文件上传到多部分表单?
答案 0 :(得分:9)
长期问题,简短回答:我在Windows下读取图像时缺少二进制模式。
f = File.new(filename, File::RDWR)
必须是
f = File.new(filename, "rb")
答案 1 :(得分:1)
另一种方法是使用Bash和Curl。当我想测试多个文件上传时,我使用了这种方法。
bash_command = 'curl -v -F "file=@texas.png,texas_reversed.png"
http://localhost:9292/fog_upload/upload'
command_result = `#{bash_command}` # the backticks are important <br/>
puts command_result