2012-05-08 72 views
14

Tôi đang làm việc trên một ứng dụng (trong Node.js, không liên quan đến trường hợp này) cho phép người dùng tải lên một hình ảnh. Nó hoạt động tốt bằng cách sử dụng một biểu mẫu với một trường đầu vào (type = "file").Chuyển đường dẫn đến tệp đã tải lên từ kéo và thả HTML5 vào trường nhập

Tuy nhiên, điều tôi muốn là có thể tải lên hình ảnh bằng cách sử dụng kéo và thả HTML5 để thay thế. Theo như tôi đã có thể kéo một hình ảnh cho khách hàng, và hình ảnh thu nhỏ được hiển thị trong một div. Tuy nhiên tôi thực sự cần một số trợ giúp khi tải tệp lên. Điều này là tôi muốn sử dụng biểu mẫu mà tôi đang sử dụng ngay bây giờ, và (bằng cách nào đó) chuyển đường dẫn của tệp đến trường nhập, tức là luồng sẽ hoạt động chính xác như hiện tại, nhưng thay vì chọn một tập tin bằng cách duyệt nó Tôi muốn đính kèm nó vào trường nhập bằng cách kéo và thả.

Trong đoạn code js dưới đây để kéo và thả các tập tin đó được kéo cho khách hàng được lưu trữ trong biến "tập tin", và tôi có thể sử dụng "file.name", "file.type" và " file.size "chính xác giống như cách nó hoạt động từ trước với biểu mẫu. Tuy nhiên, tôi không thể truy cập các tập tin "đường dẫn" (file.path) mà làm cho nó không thể truy cập vào phía máy chủ tập tin để tải lên theo cùng một cách như tôi làm điều đó từ trước.

Câu hỏi đặt ra là, có thể chuyển đối tượng tệp tới trường nhập sau khi tệp đã được kéo đến máy khách hay không, để tôi có thể nhấp vào "gửi" và tải lên tệp? Nếu vậy, làm thế nào điều này có thể được thực hiện?

Cảm ơn trước!

hộp kéo thả cũng như các hình thức Tôi đang sử dụng cho những lần tải file:

<div id='upload'> 
    <article> 
     <div id='holder'> 
      <p id='status'>File API and FileReader API not supported</p> 
     </div> 
    </article> 

    <form method='post' enctype='multipart/form-data' action='/file-upload'> 
     <p> 
      <input type='file' name='thumbnail'> 
     </p> 
     <p> 
      <input type='submit'> 
     </p> 
    </form> 
</div> 

mã cho kéo và thả:

uploadImage: function(){ 
    var holder = document.getElementById('holder'), 
     state = document.getElementById('status'); 

    if (typeof window.FileReader === 'undefined') { 
     state.className = 'fail'; 
    } else { 
     state.className = 'success'; 
     state.innerHTML = 'File API & FileReader available'; 
    } 

    holder.ondragover = function() { this.className = 'hover'; return false; }; 

    holder.ondragend = function() { this.className = ''; return false; }; 

    holder.ondrop = function (e) { 
     this.className = ''; 
     e.preventDefault(); 

     var file = e.dataTransfer.files[0], 
      reader = new FileReader(); 

     reader.onload = function (event) { 
     holder.style.background = 'url(' + event.target.result + ') no-repeat center'; 
     }; 

     reader.readAsDataURL(file); 

     return false; 
    }; 
}, 
+0

Sẽ thực sự hữu ích nếu bạn có thể tạo lại vấn đề bằng cách sử dụng http://jsfiddle.net. – tw16

Trả lời

8

Bạn không thể sử dụng đầu vào tệp để thêm dữ liệu tệp. Tuy nhiên, những gì bạn có thể làm (trong số các kỹ thuật khác) là sử dụng base64 (nguyên bản có sẵn thông qua sự kiện reader.onload dưới dạng event.target.result, khi sử dụng dữ liệu được mã hóa readAsDataURL) và đặt nó vào ẩn lĩnh vực:

html

<article> 
    <div id='holder'> 
     <p id='status'>File API and FileReader API not supported</p> 
    </div> 
</article> 

<form method='post' enctype='multipart/form-data' action='/file-upload'> 
     <input type='file' name='thumbnail' /> 
     <input type='hidden' name='base64data' /> 
     <input type='submit' formenctype='application/x-www-form-urlencoded' /> 
</form> 

js

reader = new FileReader(); 
reader.onload = function (event) { 
    document.getElementById('base64data').setAttribute('value', event.target.result); 
}; 
reader.readAsDataURL(file); 

Từ phía máy chủ bạn sẽ có thể để có được những base64 en mã hóa dữ liệu từ tệp, chỉ giải mã và sử dụng nó theo ý muốn của bạn.

Trong khi gửi biểu mẫu, bạn cũng có thể thay đổi thuộc tính "enctype" (được thực hiện thông qua thuộc tính formenctype) và xóa đầu vào tệp html cơ bản vì dữ liệu sẽ được đăng trong trường văn bản.

+1

Có thể xây dựng dữ liệu base64 từ tệp không? – joshkrz

+1

@joshkrz Khi gọi * readAsDataURL *, event.target.result là dữ liệu nhị phân của tệp được mã hóa thông qua base64.Có các phương pháp khác như * readAsBinaryString * hoặc * readAsText * sẽ dẫn đến kết quả khác. xem https://developer.mozilla.org/en-US/docs/Web/API/FileReader – challet

Các vấn đề liên quan