2012-08-08 315 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