最新のブラウザでは、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も、この機能を持っています。
もう少し説明できますか?特にJSの部分です。私が理解しているように、divに 'uploader()'関数を適用して 'アップロードフィールド'として使うべきですが、 '$ .get(" /file/blank.html ");'たぶんあなたは調べるためのユースケースがありますか? – AlexNasonov
http://www.smilingsouls.net/Blog/20110413023355.html?hSearchCursor=1/2/1から取得しています。078行目のコメントを読んでください。Safariのバグが修正されています。アップロードURLは、私のコードではdivのdata-upload_url属性にあるはずです。 –
'render_partial'への参照は何ですか? – AlexNasonov