blogサーバなど、文章だけでなく写真等のファイルを
ポストできるものがある。これにはHTMLフォーム input
要素の、type="file"
を利用する。
文字列や選択オプションを送信するフォームは たとえば以下のように記述した。
<form method="POST" action="./hoge.rb"> 一言メモ: <input name="var" size="40"><br> <input type="submit" value="SEND!"> <input type="reset" value="reset"> </form>
ファイルの中味をPOSTするには、form
の enctype
属性を multipart/form-data
に変える。
<form method="POST" enctype="multipart/form-data" action="./hoge.rb"> 一言メモ: <input name="var" size="40"><br><br> 画像を選んでね: <input name="image" type="file"> <input type="submit" value="SEND!"> <input type="reset" value="reset"> </form>
HTMLで multipart/form-data を指定して入力させた値を受け取るCGIスクリプト、 すなわちRubyプログラムは、CGI変数の受け取りを以下のように変更する。
require "cgi" cgi = CGI.new(:accept_charset => "UTF-8") memo = cgi["var"].read # CGI変数 var の受け取り(text) photo_filename = cgi["image"].original_filename # ファイル名の受け取り photo_size = cgi["image"].size # 送信ファイルサイズ取得 photo_data = cgi["image"].read # 送信ファイルデータの受け取り
このように、実際のCGIフォームでの送信値を得るには read
メソッドを介して行なう。type="file"
だけでなく
type="text"
も
read
メソッドで取得することに注意。
読み取った画像データをファイルに保存するにはたとえば以下のようにする。
open("ファイル名", "w") do |out| out.write cgi["image"].read end
保存するファイル名は上書きに留意しつつ適切に決める。 なお、ファイルを保存するディレクトリはWebサーバの権限で書き込めるよう にしておく。そのため、画像データを書き出すディレクトリは あらかじめ決めて chmod 1777 しておくとよい。
1MB以下の画像ファイル(JPEGまたはPNG)を投稿してみよ。
ソース: filepost.rb
html5に対応したブラウザのみの利用となるが、type="file"
の
input
要素に multiple
属性を付けると、
複数のファイル選択をさせることが可能となる。
この場合、Rubyプログラムで受け取るCGI変数は、値を配列で受け取れる ように CGI#params を利用する。たとえばHTML側で、
<input name="memo" type="text"> <input name="memo" type="text">
のように同じCGI変数 memo で複数の値を送信することもできる。 これをRubyプログラム側で処理するには
require 'cgi' cgi = CGI.new(:accept_charset => "UTF-8") v_memo = cgi.params["memo"]
のようにする。v_memo[0]
で1つ目のinputフォーム値が、
v_memo[1]
で2つ目のinputフォーム値が受け取れるようになる。
これは他のtypeでも同様である。ただし、
enctype="multipart/form-data"
の場合にはそれぞれ
v_memo[0].read, v_memo[1].read
のようにさらに
read
メソッドを呼んで実際のCGI変数値が取得できる。
以上のことを利用して、複数のファイルをまとめて投稿させ、 それらのサムネイル画像を生成し、サムネイルから元の画像にリンクした Webページを自動生成するCGIプログラムの例を以下に示す。 実際に複数の画像を与えてみよ。
ソース: multipost.rb