今天用 firefox 收信的時候,意外發現它可以將桌面上的檔案拖曳進來,然後直接上傳。以往如果之前別人問我能不能用純 ajax 上傳檔案的話,我一定毫不猶豫、斬釘截鐵的說不行。現在在 HTML5 的支援下,看來以後不能再這麼斬釘截鐵了。
照著該文章的寫法做了一次,有部份小修改,順便寫了點中文註解:
<div id="dropzone" style=" border:1px solid black;height:200px;width:200px"></div> <script type="text/javascript"> function upload(event) { var data = event.dataTransfer; /* 這個是 RFC2388 的規範,算是二進位資料之間的分隔符號 */ var boundary = '------multipartformboundary' + (new Date).getTime(); var dashdash = '--'; var crlf = '\r\n'; /* 組出 Request 字串 */ var builder = ''; builder += dashdash; builder += boundary; builder += crlf; var xhr = new XMLHttpRequest() for (var i = 0; i < data.files.length; i++) { var file = data.files[i]; /* 檔案的標頭 */ builder += 'Content-Disposition: form-data; name="files"'; if (file.fileName) { builder += '; filename="' + file.name + '"'; } builder += crlf; builder += 'Content-Type: ' + file.type; builder += crlf; builder += crlf; /* 檔案內容 */ builder += file.getAsBinary(); builder += crlf; /* 檔案間的分隔字串 (boundary) */ builder += dashdash; builder += boundary; builder += crlf; } /* Request 結尾 */ builder += dashdash; builder += boundary; builder += dashdash; builder += crlf; /* 直接用 XmlHttpRequest 送出,也就是傳說中的 ajax */ xhr.open("POST", "/home/upload", true); xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary); xhr.sendAsBinary(builder); /* Prevent FireFox opening the dragged file. */ event.stopPropagation(); event.preventDefault(); } document.getElementById("dropzone").ondrop = upload; document.ondragover = function (event) {event.preventDefault();}; </script>
整段程式最主要就是靠 event.dataTransfer.files 陣列在運作,依序組出整個 HttpRequest 的內容,然後再用 ajax 回傳到伺服器端,還可以一次拖曳多個檔案:
就這樣,沒有 PostBack、瀏覽器也不會閃一下,漂亮的完成以往要用 Silverlight 、Flash 才辦得到的檔案上傳。可惜我用習慣的 IE 要等到 10 才會開始支援。
另外,在該篇文章底下討論串還看到這個連結,看起來似乎能夠更方便的使用 ajax 上傳功能。
沒有留言:
張貼留言