2012-08-08 319 views
10

我沒有獲取附件上傳以使瀏覽器正常工作。如何從瀏覽器上傳文件(附件)?

一些提示是here,其他thereThe docs是相當不錯的,但我無法將其翻譯成AJAX上傳。

我在尋找一個超級簡單的HTML/JavaScript的例子(有或W/O的jQuery)如何上傳(相對現代的)瀏覽器的分貝文件而不利用jquery.couch.app的.js包裝或東西。 besser越簡單越好。

任何幫助表示讚賞。

回答

18

好吧,這裏是您純粹的JavaScript文件上傳實施。

的基本算法是這樣的:

  1. 從文件輸入元素
  2. 獲取的文件獲取文件名稱和類型關閉文件對象
  3. 獲取文檔的最新文件修改你要將該文件附加到
  4. 附加文件使用取修訂記錄

的HTML部分基本上由一個帶有兩個元素的簡單表單組成,一個類型爲file的輸入和一個類型爲submit的按鈕。

<form action="/" method="post" name="upload"> 
    <input type="file" name="file" /> 
    <button type="submit" name="submit">Upload</button> 
</form> 

現在轉到JavaScript部分。

window.onload = function() { 
    var app = function() { 
     var baseUrl = 'http://127.0.0.1:5984/playground/'; 
     var fileInput = document.forms['upload'].elements['file']; 
     document.forms['upload'].onsubmit = function() { 
      uploadFile('foo', fileInput.files[0]); 
      return false; 
     }; 

     var uploadFile = function(docName, file) { 
      var name = encodeURIComponent(file.name), 
      type = file.type, 
      fileReader = new FileReader(), 
      getRequest = new XMLHttpRequest(), 
      putRequest = new XMLHttpRequest(); 

      getRequest.open('GET', baseUrl + encodeURIComponent(docName), 
       true); 
      getRequest.send(); 
      getRequest.onreadystatechange = function(response) { 
       if (getRequest.readyState == 4 && getRequest.status == 200) { 
        var doc = JSON.parse(getRequest.responseText); 
        putRequest.open('PUT', baseUrl + 
         encodeURIComponent(docName) + '/' + 
         name + '?rev=' + doc._rev, true); 
        putRequest.setRequestHeader('Content-Type', type); 
        fileReader.readAsArrayBuffer(file); 
        fileReader.onload = function (readerEvent) { 
         putRequest.send(readerEvent.target.result); 
        }; 
        putRequest.onreadystatechange = function(response) { 
         if (putRequest.readyState == 4) { 
          console.log(putRequest); 
         } 
        }; 
       } 
      }; 
     }; 
    }; 
    app(); 
}; 

基本上,我用我自己的功能結合到窗體的onsubmit事件並返回false攔截submit活動形式。

在那個事件處理程序中,我用兩個參數調用我的主函數。第一個是文檔名稱,第二個是要上傳的文件。

在我的uploadFile()函數中,我設置文件名,文件類型並獲取一些實例。第一個HTTP請求是一個獲取文檔當前版本的GET請求。如果該請求成功,我通過設置先前獲得的修訂,準備好PUT請求(實際的上載請求),正確的內容類型,然後將文件轉換爲ArrayBuffer。一旦完成,我只是發送我剛剛準備好的HTTP請求,然後放鬆一下。

單機附件上傳方案看起來像這樣:

PUT host/database/document/filename?revision=latest-revision 

當然使用在HTTP請求報頭中的適當的內容類型。

注意:我很清楚,我沒有在這裏使用防禦性編程,所以爲了簡潔起見,我故意這樣做了。

+0

很好的例子和解釋。這正是我所期待的! – Jlange 2013-01-01 18:15:54

+1

請注意,由於jQuery不支持ArrayBuffer對象,這是readerEvent.target.result返回的內容,因此未在此使用jQuery。這花了我幾個小時才弄清楚,所以我會爲其他人寫下來。 – samoz 2014-04-23 16:14:01

+1

真的很好的答案,但是使用名爲'document'的局部變量是IMO在客戶端JavaScript中的一個否定。只是說... – 2016-04-26 10:35:57