如 ryan dahl所述,这个过程如下:
HTTP upload progress bars are rather obfuscated- they typically involve a process running on the server keeping track of the size of the tempfile that the HTTP server is writing to,then on the client side an AJAX call is made every couple seconds to the server during the upload to ask for the progress of the upload.
每次上传都有一个随机的会话ID,并跟踪我在应用程序中使用一个类变量的关联(我知道这太可怕了 – 如果你有更好的想法,请告诉我)
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 || = {}}
>我也试过在它上面抛出一个关系数据库(sqlite with DataMapper)
没有工作.
解决方法
tmp = params [:file] [:tempfile]不会返回,直到文件被完全收到.