接下來這個範例顯示如何非同步的上傳檔案到伺服器。
新增上傳的工作
接續先前創建縮圖的範例,將每個縮圖都設置 CSS class “obj”, 這使得我們可以很容易地使用
Document.querySelectorAll()
選擇使用者要上傳的圖檔,例如:function sendFiles() {
var imgs = document.querySelectorAll(".obj");
for (var i = 0; i < imgs.length; i++) {
new FileUpload(imgs[i], imgs[i].file);
}
}
第二行創建了
imgs
陣列,存放著所有文件中 CSS class 為 “obj” 的 Node。在這個範例中,我們使用這個來創建縮圖。Once we have that list, it's trivial to go through the list, creating a new FileUpload
instance for each. Each of these handles uploading the corresponding file.處理上傳檔案的程序
FileUpload
函數接受圖檔和檔案.function FileUpload(img, file) {
var reader = new FileReader();
this.ctrl = createThrobber(img);
var xhr = new XMLHttpRequest();
this.xhr = xhr;
var self = this;
this.xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
self.ctrl.update(percentage);
}
}, false);
xhr.upload.addEventListener("load", function(e){
self.ctrl.update(100);
var canvas = self.ctrl.ctx.canvas;
canvas.parentNode.removeChild(canvas);
}, false);
xhr.open("POST", "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
reader.onload = function(evt) {
xhr.sendAsBinary(evt.target.result);
};
reader.readAsBinaryString(file);
}
FileUpload()
函數創建被用來顯示上傳進度的 throbber,接著創建 XMLHttpRequest
上傳檔案.
傳輸資料前的幾個準備工作:
- The
XMLHttpRequest
's upload "progress" listener is set to update the throbber with new percentage information, so that as the upload progresses, the throbber will be updated based on the latest information. - The
XMLHttpRequest
's upload "load" event handler is set to update the throbber with 100% as the progress information (to ensure the progress indicator actually reaches 100%, in case of granularity quirks during the process). It then removes the throbber, since it's no longer needed. This causes the throbber to disappear once the upload is complete. - The request to upload the image file is opened by calling
XMLHttpRequest
'sopen()
method to start generating a POST request. - The MIME type for the upload is set by calling the
XMLHttpRequest
functionoverrideMimeType()
. In this case, we're using a generic MIME type; you may or may not need to set the MIME type at all, depending on your use case. - The
FileReader
object is used to convert the file to a binary string. - Finally, when the content is loaded the
XMLHttpRequest
functionsendAsBinary()
is called to upload the file's content.
非同步處理上傳檔案的程序
function fileUpload(file) {
// Please report improvements to: marco.buratto at tiscali.it
var fileName = file.name,
fileSize = file.size,
fileData = file.getAsBinary(), // works on TEXT data ONLY.
boundary = "xxxxxxxxx",
uri = "serverLogic.php",
xhr = new XMLHttpRequest();
xhr.open("POST", uri, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); // simulate a file MIME POST request.
xhr.setRequestHeader("Content-Length", fileSize);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status <= 200) || xhr.status == 304) {
if (xhr.responseText != "") {
alert(xhr.responseText); // display response.
}
}
}
}
var body = "--" + boundary + "\r\n";
body += "Content-Disposition: form-data; name='fileId'; filename='" + fileName + "'\r\n";
body += "Content-Type: application/octet-stream\r\n\r\n";
body += fileData + "\r\n";
body += "--" + boundary + "--";
xhr.send(body);
return true;
}
使用二進制數據時,這些程式碼還需要修改。
From: https://developer.mozilla.org/zh-TW/docs/Web/API/File/Using_files_from_web_applications#%E7%AF%84%E4%BE%8B%EF%BC%9A%E4%B8%8A%E5%82%B3%E6%AA%94%E6%A1%88