我正在开发一个Sinatra应用程序,其中包含一个上传表单,其中包含一个进度条,指示已完成上载的内容。 正如ryan dahl所述,该过程如下:
HTTP上传进度条相当混淆 - 它们通常涉及在服务器上运行的进程,跟踪HTTP服务器正在写入的临时文件的大小,然后在客户端,每隔几秒就进行一次AJAX调用。上传期间服务器要求上传进度。
每次上传都有一个随机session-id
,并且为了跟踪我在我的应用中使用class variable
的关联(我知道,这太可怕了 - 如果你有更好的想法,请告诉我们我)
configure do
@@assoc = {}
end
我有一个POST
路由用于上传,而GET
路由用于AJAX轮询。
在POST
路线中,我保存了session-id
,Tempfile
和总大小的关联。
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 ||= {} }
两者都没有。
答案 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'] }