Archive for 7月 19th, 2009



Ruby::cgi で multipart 送信のときのフォームの値の取得方法

日曜日, 7月 19th, 2009

久々にハマった。デバッグに数十分もかかってしまった。

後から思えば簡単なことなのになんで気が付かないんだろ。

たとえば、以下のようなファイルをアップロードする CGI を作ろうとすると、コードは多分こんなかんじになる。

#!/usr/bin/ruby

require 'cgi'

cgi = CGI.new
filename = ""
text = ""
if cgi.has_key?("upload")
  filename = cgi['file'].original_filename
  text = cgi['text']
end

puts <<EOM
<form action="KORE.rb" method="POST" enctype="multipart/form-data">
 <input type="file"   name="file" />
 <input type="text"    name="aaaa"  />
 <input type="submit" name="upload" value="送信" />
</form>

<p>
#{CGI.escapeHTML(filename)}<br />
#{CGI.escapeHTML(aaaa)}
</p>
EOM

ソースどおりですが、アップロードしたファイル名とテキストボックスのデータを <p> のところに表示させる、という CGI です。
ところが、これは希望通りに動作しません。

具体的にはテキストボックスのデータ表示が「#<String…」のように OBJ.class の値しかかえってきません。
これは multipart で送信しているからなので、以下のようにしないといけない。multipart でなければ上のソースで OK 。

#!/usr/bin/ruby

require 'cgi'

cgi = CGI.new
filename = ""
text = ""
if cgi.has_key?("upload")
  filename = cgi['file'].original_filename
  text = cgi['text'].read
end

puts <<EOM
<form action="KORE.rb" enctype="multipart/form-data" method="POST">
 <input name="file" type="file" />
 <input name="aaaa" type="text" />
 <input name="upload" type="submit" value="送信" />
</form>

<p>
#{CGI.escapeHTML(filename)}<br />
#{CGI.escapeHTML(aaaa)}
</p>
EOM

はい、read を付けるだけです。リファレンスいいかげんにしか見てないからこんなことになるんでしょうね…。