2011-09-23 62 views
5

我的javascript功能只能正确上传文本文件。任何人都可以帮我弄清楚如何让它也接受图像等?Javascript未上传二进制数据

function fileUpload(files) { 
    if (!files.length) { 
    fileList.innerHTML = "<p>No files selected!</p>"; 
    } else {  
var list = document.createElement("ul"); 

for (var i = 0; i < files.length; i++) { 

    //Set vars 
    var file = files[i], 
    fileName = file.name, 
    fileSize = file.size, 
    fileData = file.getAsBinary(), 
    boundary = "xxxxxxxxx", 
    uri = "receive.php", 

    //Create file info HTML output 
    li = document.createElement("li"); 
    list.appendChild(li); 
    var info = document.createElement("span"); 
    info.innerHTML = file.name + ": " + file.size + " bytes"; 
    li.appendChild(info); 

    //Start sending file 
    var xhr = new XMLHttpRequest(); 
    xhr.open("POST", uri, true); 
    xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); // simulate a file MIME POST request. 

    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='upload'; filename='" + fileName + "'\r\n"; 
    body += "Content-Type: application/octet-stream\r\n\r\n"; 
    body += fileData + "\r\n"; 
    body += "--" + boundary + "--"; 

    xhr.send(body); 

} 
fileList.appendChild(list); 
return true; 
    } 
} 

更新:我发现下面的功能在网上http://code.google.com/p/html5uploader/但我无法弄清楚如何将其应用到我的当前功能。 xhr.sendAsBinary是唯一改变了的事情吗?

// Upload image files 
upload = function(file) { 

    // Firefox 3.6, Chrome 6, WebKit 
    if(window.FileReader) { 

     // Once the process of reading file 
     this.loadEnd = function() { 
      bin = reader.result;     
      xhr = new XMLHttpRequest(); 
      xhr.open('POST', targetPHP+'?up=true', true); 
      var boundary = 'xxxxxxxxx'; 
      var body = '--' + boundary + "\r\n"; 
      body += "Content-Disposition: form-data; name='upload'; filename='" + file.name + "'\r\n"; 
      body += "Content-Type: application/octet-stream\r\n\r\n"; 
      body += bin + "\r\n"; 
      body += '--' + boundary + '--';  
      xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary); 
      // Firefox 3.6 provides a feature sendAsBinary() 
      if(xhr.sendAsBinary != null) { 
       xhr.sendAsBinary(body); 
*snip* 
+0

你如何检索文件。我的意思是文件参数必须在某处提供。你是怎样做的?我需要通过ajax来解释这个文件上传的问题。任何帮助将不胜感激。 – user1575229

+0

@ user1698985我不确定你的意思,你的意思是在PHP端检索它?在这种情况下,您可以在POST数据中找到它。 – natli

+0

在服务器端检索它是另一个讨论。我只想找到加载到表单数据并通过ajax发送的客户端上选择文件的方式。在Html5中很容易。但我不明白它是如何在以前的版本的HTML。我试图窥探ajaxform插件,但很难理解它是如何检索文件数据并通过ajax发送的。我想了解整个过程,从jquery中选择文件到处理并提交给服务器。 – user1575229

回答

2

有一个在http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2发送使用multipart/form-data GIF图像的W3C例如:

 
Content-Type: multipart/form-data; boundary=AaB03x 

--AaB03x 
Content-Disposition: form-data; name="submit-name" 

Larry 
--AaB03x 
Content-Disposition: form-data; name="files" 
Content-Type: multipart/mixed; boundary=BbC04y 

--BbC04y 
Content-Disposition: file; filename="file1.txt" 
Content-Type: text/plain 

... contents of file1.txt ... 
--BbC04y 
Content-Disposition: file; filename="file2.gif" 
Content-Type: image/gif 
Content-Transfer-Encoding: binary 

...contents of file2.gif... 
--BbC04y-- 
--AaB03x-- 

通知额外线Content-Transfer-Encoding: binary。尝试添加。

编辑:尝试Base64编码,使用the Base64 jQuery plugin文件数据:

var body = "--" + boundary + "\r\n"; 
    body += "Content-Disposition: form-data; name='upload'; filename='" + fileName + "'\r\n"; 
    body += "Content-Type: application/octet-stream\r\n"; 
    body += "Content-Transfer-Encoding: base64\r\n\r\n"; 
    body += $.base64Encode(fileData) + "\r\n"; 
    body += "--" + boundary + "--"; 
+0

不幸的是,这并没有改变一件事。文本文件仍然正确上传,但图像不正确。图像最终损坏了服务器,大约是正常文件大小的两倍。然而,我确实在网上找到了一个我想要的功能,但由于我是JavaScript新手,我不知道如何将它实现到我自己的功能中。 (查看更新的问题)由于我缺乏经验,我也不明白你的问题,为什么它必须是body.length? – natli

+0

@natli:[因为Firefox显然是唯一支持'sendAsBinary()'的浏览器](http://stackoverflow.com/q/4236153/196844),它看起来像是使用FF的内置'sendAsBinary() '方法,但在Chrome和Safari上,他们实现了一个解决方法(尽管只是猜测)。无论如何,二进制文件应该先用base64编码。然后设置“Content-Transfer-Encoding:base64”。就Content-Length而言,这是不能使用'setRequestHeader()'方法设置的标题之一(http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method)。所以,不要担心。 –

+0

@natli:我更新了我的答案。 –