2012-01-14 3 views
1

Я создаю загрузчик для своего проекта, и я стараюсь избегать любых флеш-решений (мне не нравится флэш-память и поддержка мобильных платформ). Весь процесс кажется довольно простым: у меня есть форма, хороший индикатор выполнения jQuery, я могу сделать запросы ajax с тайм-аутом из сценария, чтобы обновить статус progressbar ... Если я делаю это согласно Cookbook Webpy, единственное, что я делаю 't get - как получить любую информацию с сервера: сколько байтов/кусков/что-то еще было написано?Получить статус загрузки в webpy

ответ

2

Вы можете создать загрузчик ajax, используя FormData для современных браузеров.

$.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. Как я понял, я должен применить функцию 'uploader()' для div и использовать ее как «поле для загрузки», но что такое '$ .get (" /file/blank.html ");' строка для? Может быть, у вас есть пример использования? – AlexNasonov

+0

Это взято из http://www.smilingsouls.net/Blog/20110413023355.html?hSearchCursor=1/2/1 Просто прочитайте комментарий там, в строке 078. Он исправляет некоторые ошибки Safari. Что касается URL-адреса загрузки, в моем коде он должен быть в атрибуте data-upload_url div. –

+0

и что ссылка на 'render_partial'? – AlexNasonov

Смежные вопросы