如果你要傳送二進位資料給瀏覽器,可以使用send_data方法,說是傳遞二進位資料,實際上是提供ASCII-8BIT字串給send_data方法,send_data會取得字串的位元組資料,預設以content-type為application/octet-stream送出。舉例來說,如果想以二進位方式傳送文字資料,並提示客戶端可以儲存為message.txt,可以如下:
send_data "test", :filename => "message.txt"
如果要指定型態,可以使用:type(預設是application/octet-stream),:disposition可指定inline或attachment(預設),:status可指定狀態碼(預設200)。
使用send_data的一個時機,是使用程式動態產生圖片後,將圖片送給客戶端,以 How to use RMagick 中的一個圖片產生範例(要安裝RMagick,可參考 Install ImageMagick From Source),如果要將產生的圖片送回,可以如下:
# 記得要在Gemfile後加入gem 'rmagick',然後執行bundle install
require 'RMagick'
def logo
send_data image_data, :type => "image/gif", :disposition => 'inline'
end
def image_data
canvas = Magick::ImageList.new
canvas.new_image(250, 250, Magick::HatchFill.new('white', 'gray90'))
circle = Magick::Draw.new
circle.stroke('tomato')
circle.fill_opacity(0)
circle.stroke_opacity(0.75)
circle.stroke_width(6)
circle.stroke_linecap('round')
circle.stroke_linejoin('round')
circle.ellipse(canvas.rows/2,canvas.columns/2, 80, 80, 0, 315)
circle.polyline(180,70, 173,78, 190,78, 191,62)
circle.draw(canvas)
canvas.to_blob {self.format = "gif"} # 以ASCII-8BIT字串傳回
end
實際上send_data使用了render方法來傳送資料:
# File actionpack/lib/action_controller/metal/data_streaming.rb, line 104
def send_data(data, options = {}) #:doc:
send_file_headers! options.dup
render options.slice(:status, :content_type).merge(:text => data)
end
如果要傳送的是個檔案,則可以使用send_file方法,這個方法接受檔案路徑,會將指定的檔案讀入,並傳送給瀏覽器,send_data支援的選項,send_file也都支援,除此之外,還支援:stream,預設是false,表示將整個檔案載入記憶體,如果檔案很大,可以將之設為true,:buffer_size則用來設定串流暫存空間,預設是4096位元組。
例如,以下是驗證密碼正確後,傳送PDF檔案的一個範例:
if params[:passwd] == "123456"
send_file "/home/caterpillar/ACL034000.pdf", :type => "application/pdf"
end
end