Google Code Prettify

[Javascript]上傳檔案

接下來這個範例顯示如何非同步的上傳檔案到伺服器。

新增上傳的工作

接續先前創建縮圖的範例,將每個縮圖都設置 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 上傳檔案.
傳輸資料前的幾個準備工作:
  1. 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.
  2. 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.
  3. The request to upload the image file is opened by calling XMLHttpRequest's open() method to start generating a POST request.
  4. The MIME type for the upload is set by calling the XMLHttpRequest function overrideMimeType(). 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.
  5. The FileReader object is used to convert the file to a binary string.
  6. Finally, when the content is loaded the XMLHttpRequest function sendAsBinary() is called to upload the file's content.
註: 範例中非標準的 sendAsBinary 方法已經在 Gecko 31 (Firefox 31 / Thunderbird 31 / SeaMonkey 2.28) 廢棄且很快將會被移除。可以改使用標準的 send(Blob data)。

非同步處理上傳檔案的程序

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