Certa vez, anos atrás, pesquisei como seria possível fazer upload de arquivos do desktop direto para uma aplicação web, arrastando-e-colando. Não era.
A única coisa que achei seria implementando um java applet ou alguma solução proprietária – a Microsoft tem um lance desses no Sharepoint, o CMS deles. Desencanei.
Ai, semana passada saiu uma notícia que era possível fazer isso pelo Gmail. Acredito que a solução a qual eles chegaram não é a mesma que eu encontrei na web, mas acredito que seja algo do gênero. Basicamente, dá pra fazer isso com HTML5 se você estiver usando um browser adequado. Adequado, nesse contexto, é o Chrome 2.0+ ou Firefox 3.6
Não vou me dar ao trabalho de fazer uma explicação muito didática; se você chegou até aqui, acredito que tenha experiência em desenvolvimento de interfaces web e vai entender o que estou falando. Se não, dê alguns passos para trás antes de continuar.
Com o HTML5, muita coisa diferente em javascript foi implementada. Para o usuário poder arrastar-e-colar arquivos do file system para uma interface web, são usadas 2 funcionalidades (desculpem o nome, não achei um mais adequado):
- File API
- XMLHttpRequest 2
Com o primeiro (File API), você consegue manipular arquivos que são “arrastados-e-colados” para uma certa área da sua página. Manipular, nesse caso, pode ser muita coisa, mas você consegue saber o nome, file syze, content type, conteúdo do mesmo (em binário, por exemplo), etc…
Com o XMLHttpRequest versão 2 é possível fazer o envio de dados nas suas requisições em formato binário. E bacana é que existem métodos nativos para saber o status e a porcentagem da mesma – ou seja, você consegue criar uma progress bar, por exemplo.
Vou colar logo abaixo o conteúdo da página de teste, que possui comentários. Sei que o post ficou meio superficial, mas ele serve mais como referência para vocês saberem mais uma coisa do que é possível ser feito com HTML5!
Url de teste: http://www.chrisb.com.br/teste.html
*no caso, arraste arquivos do file system para a caixa com bordas pretas.
<html>
<head>
<script>
function dodrop(event) {
//retorna os arquivos que estão sendo transferidos
var dt = event.dataTransfer;
var files = dt.files;
//percorre os arquivos
var count = files.length;
output(“File Count: ” + count + “\n”);
for (var i = 0; i < files.length; i++) {
//escreve infotmações do arquivos
output(” File ” + i + “:\n(” + (typeof files[i]) + “) : <” + files[i] + ” > ” +
files[i].name + ” ” + files[i].size + “\n”);
new FileUpload(files[i]); //instancia objeto dessa classe, passando o arquivo para o construtor
}
}
function output(text) {
document.getElementById(“output”).textContent += text;
dump(text);
}
function FileUpload(file) {
//cria objeto para requisições assíncronas
var xhr = new XMLHttpRequest();
//cria listeners para o upload (que é quando o xmlhttprequest está enviando o arquivo):
//para o durante o processo
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
document.getElementById(“p”).innerHTML = percentage;
}
}
//caso ocorra algum erro
xhr.upload.onerror = function(e){
alert(“Erro”);
}
//quando finalizar o upload
xhr.upload.onload = function(event){
document.getElementById(“p”).innerHTML = 100;
}
//abre a conexão; o segundo parâmetro é da url a ser requisitada, que recebe o arquovo
xhr.open(“POST”, “http://www.chrisb.com.br/up.php”);
xhr.overrideMimeType(‘text/plain; charset=x-user-defined-binary’);
//cria objeto FileReader para ler o arquivo
var reader = new FileReader();
//quando acabar de ler o arquivo…
reader.onload = function(e) {
//pega o retorno da função, que é um dado binário
var bin = e.target.result;
//e faz o xmlhttprequest enviar como binário
xhr.sendAsBinary(bin);
};
reader.readAsBinaryString(file); //lê o arquivo como binário
}
window.onload = function() {
var output = document.getElementById(“output”);
output.ondragenter = function(event) {
document.getElementById(‘output’).textContent = ”; event.stopPropagation(); event.preventDefault();
}
output.ondragover = function(event) {
event.stopPropagation(); event.preventDefault();
}
output.ondrop = function(event) {
event.stopPropagation(); event.preventDefault();
dodrop(event);
}
}
</script>
</head>
<body>
<div id=”output” style=”min-height: 100px; white-space: pre; border: 1px solid black;”></div>
<span id=”p”></span>
</body>
</html>