Sinatra,上传表格中的进度条

时间:2010-06-22 18:21:20

标签: ruby iframe file-upload sinatra mongrel

我正在开发一个Sinatra应用程序,其中包含一个上传表单,其中包含一个进度条,指示已完成上载的内容。 正如ryan dahl所述,该过程如下:

  

HTTP上传进度条相当混淆 - 它们通常涉及在服务器上运行的进程,跟踪HTTP服务器正在写入的临时文件的大小,然后在客户端,每隔几秒就进行一次AJAX调用。上传期间服务器要求上传进度。

每次上传都有一个随机session-id,并且为了跟踪我在我的应用中使用class variable的关联(我知道,这太可怕了 - 如果你有更好的想法,请告诉我们我)

configure do
  @@assoc = {}
end

我有一个POST路由用于上传,而GET路由用于AJAX轮询。 在POST路线中,我保存了session-idTempfile和总大小的关联。

post '/files' do
  tmp = params[:file][:tempfile]
  # from here on, @@assoc[@sid] should have a value, even in other routes
  @@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] } 
  File.open("#{options.filesdir}/#{filename}", 'w+') do |file|
    file << tmp.read
  end
end 

GET路线中,我根据Tempfile的当前尺寸计算百分比:

get '/status/:sid' do
  h = @@assoc[params[:sid]]
  unless h.nil?
    percentage = (h[:file].size / h[:size].to_f) * 100 
    "#{percentage}%"
  else
    "0%"
  end 
end

问题是,在POST请求未完成之前(即,在读完所有Tempfile之后),h.nil?会返回true,这不会我真的有意义,因为我刚刚在另一条路线中为@@assoc[@sid]分配了一个值。

那么,我在这里错过了什么?

编辑:我试过

  • set :reload, false
  • set :environment, :production
  • config { @@assoc ||= {} }
  • 我也尝试过抛出一个关系数据库(带有DataMapper的SQLite)

两者都没有。

2 个答案:

答案 0 :(得分:4)

我想我遇到了问题所在:

tmp = params[:file][:tempfile]在文件完全收到之前不会返回。

答案 1 :(得分:1)

@@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] }

应该是

@@assoc[params[:sid]] = { :file => tmp, :size => env['CONTENT_LENGTH'] }