2012-01-14 6 views
1

私は自分のプロジェクトのアップローダーを作っています。私はFlashベースのソリューションを避けようとしています。 プロセス全体がかなりシンプルに見えます:私はフォーム、素敵なjQueryのプログレスバーを持っています。スクリプトからプログレスバーのステータスを更新するためにタイムアウトを使ってajaxリクエストを作ることができます... 私はWebpyの料理ブックに従って、サーバーから情報を受け取る方法は何ですか:既に何バイト/チャンク/何が書かれていますか?webpyのアップロード状況を取得

答えて

2

最新のブラウザでは、FormDataを使用してajax uploaderを作成できます。私はこのようにそれを処理するサーバー側で

$.fn.uploader = function(options) { 
    var defaults = {}, 
     opts = $.extend(defaults, options), 
     that = $(this), 
     url = that.data("upload_url"), 
     is_uploading = false; 

    function upload(files) { 

     $.get("/file/blank.html"); 

     if (FormData === undefined) { 
      alert("Your browser does not support standard HTML5 Drag and Drop"); 
      return; 
     }   

     var xhr = new XMLHttpRequest(), 
      new_element = $("<li><p>Loading</p><span></span></li>") 
       .appendTo(that), 
      xhr_upload = xhr.upload, 
      form = new FormData(); 

     xhr_upload.addEventListener("progress", function(e) { 
      if(e.lengthComputable) { 
       var p = Math.round(e.loaded * 100/e.total); 
       new_element.children("span").text(e.loaded == e.total ? "Processing..." : p + "%"); 
      } 
     }, false); 
     xhr_upload.addEventListener("load", function(e){}, false); 
     xhr_upload.addEventListener("error", function(error) { alert("error: " + error); }, false); 

     xhr.open("POST", url, true); 
     xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 

     xhr.onreadystatechange = function (e) { 
      if (xhr.readyState == 4) { 
       is_uploading = false; 
       if(xhr.status == 200) { 
        var data = $.parseJSON(e.target.responseText); 
        if (data.status == 0) { 
         new_element 
          .fadeOut(function(){ $(this).remove(); }) 
          .children("span").text("Upload error!"); 
        } else { 
         that.html(data.html); 
        } 
       } else { 
        new_element 
         .fadeOut(function(){ $(this).remove(); }) 
         .children("span").text("Upload error!"); 
       } 
      } 
     }; 
     $.each(files, function() { 
      form.append("files", this); 
     }); 
     is_uploading = true; 
     xhr.send(form); 
    } 

    that.bind({ 
     "dragover": function(e) { 
      var dt = e.originalEvent.dataTransfer; 
      if(!dt || is_uploading) { return; }; 
      if($.browser.webkit) { dt.dropEffect = "copy"; }; 
      $(this).addClass("active"); 
      return false; 
     }, 
     "dragleave": function(e) { 
      $(this).removeClass("active"); 
     }, 
     "dragenter": function(e){ return false; }, 
     "drop": function(e){ 
      var dt = e.originalEvent.dataTransfer; 
      $(this).removeClass("active"); 
      if(!dt || !dt.files || is_uploading) { return; }; 
      upload(dt.files); 
      return false; 
     } 
    }); 

    $(document).bind({ 
     'dragenter': function(e) { return false; }, 
     'dragleave': function(e) { return false; }, 
     'dragover': function(e) { 
      var dt = e.originalEvent.dataTransfer; 
      if (!dt) { return; } 
      dt.dropEffect = "none"; 
      return false; 
     } 
    }); 

}; 

def POST(self): 
    i = web.webapi.rawinput() 
    try: 
     files = i.files 
     if not isinstance(files, list): 
      files = [files] 
     for f in files: 
      if f.filename: 
       filetype, encoding = mimetypes.guess_type(f.filename) 
       # do smth with f.file 
    except KeyError: 
     pass 
    if web.ctx.env.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest': 
     web.header("Content-Type", "application/json") 
     return json.dumps(dict(status=1, html=unicode(render_partial.files(uploaded_files)))) 
    else: 
     raise web.seeother(web.ctx.env.get("HTTP_REFERER", "/")) 

そうでなければ、あなたがnginx upload progressモジュールまたはapache2のアップロードの進行状況モジュールに見えるかもしれuWSGIも、この機能を持っています。

+0

もう少し説明できますか?特にJSの部分です。私が理解しているように、divに 'uploader()'関数を適用して 'アップロードフィールド'として使うべきですが、 '$ .get(" /file/blank.html ");'たぶんあなたは調べるためのユースケースがありますか? – AlexNasonov

+0

http://www.smilingsouls.net/Blog/20110413023355.html?hSearchCursor=1/2/1から取得しています。078行目のコメントを読んでください。Safariのバグが修正されています。アップロードURLは、私のコードではdivのdata-upload_url属性にあるはずです。 –

+0

'render_partial'への参照は何ですか? – AlexNasonov

関連する問題