miércoles, 3 de julio de 2013

Subir archivos con Ajax

//------------------------------------------------------------------------------------------------
// Engines      JavaScript 1.8.5+
//              JScript    10+
// Environments IE10+ FIREFOX4+ CHROME6+ OPERA12+ SAFARI5+
//------------------------------------------------------------------------------------------------
function upload 
(
      s // action-url
    , e // input file (id | element)
    , u // user
    , p // password
){
    if (typeof e != 'object')
        e = document.getElementById(e);
 
    var f, l = 0;

    if ((f = e.files) && (l = f.length) == 1) // HTML5! (FileList)
    {
        var h = new XMLHttpRequest();
  
        h.open('POST', s, false, u, p);
        h.setRequestHeader('Content-type', 'multipart/form-data');
        h.setRequestHeader('X-File-Name', (f = f[0]).name);
        h.setRequestHeader('X-File-Size', f.size);
        h.setRequestHeader('X-File-Type', f.type);
        h.send(f);
  
        return h.readyState == 4 && h.status == 200;
    }
 
    else if (l > 1)
    {
        f = [];
        for (var i = 0; i < l; ++i) f.push
        ({
               fileName : e.files[i].name
             , uploaded : upload(s, {files: [e.files[i]]}, u, p)
        });
  
        return f;
    }
 
    return false;
}

Uso con un sólo archivo:

<input id="file" type="file" />
if (upload('upload.php', 'file'))
{
    //TODO...
}

Uso con múltiples archivos:

<input id="files" type="file" multiple />
var r = upload('upload.php', 'files');

for (var i = 0, l = r.length; i < l; ++i) if (!r[i].uploaded) 
{
    alert('"' + r[i].fileName + '" Not uploaded correctly!');
    // TODO...
}


upload.php:
<?php

$hd   = getallheaders();
$name = $hd["X-File-Name"];

if (strlen($name) > 0)
{
    //$size = $hd["X-File-Size"];
    //$type = $hd["X-File-Type"];
    // TODO...

    $in  = fopen("php://input", "r");
    $out = fopen("upload/" . $name, "w");
    while($data = fread($in, 1024)) fwrite($out, $data);
    fclose($out);
    fclose($in);
}

?>
upload.jsp:
<%@ page import="java.io.*" %>
<%
    String fileName = request.getHeader("X-File-Name");
    if (fileName != null && fileName.length() > 0)
    {
        //String fileSize = request.getHeader("X-File-Size"); 
        //String fileType = request.getHeader("X-File-Type");    
        //TODO..
    
        FileOutputStream fos    = new FileOutputStream("webapps/test/upload/" + fileName);
        InputStream      is     = request.getInputStream();
        byte[]           buffer = new byte[1024];
        int              length = 0;
    
        while ((length = is.read(buffer)) != -1)
            fos.write(buffer, 0, length);
  
        fos.flush();
        fos.close();
    }
%>
upload.aspx:
<%@ Page Language="C#" %>
<%
if (Request.ContentLength > 0)
{
    string fileName = Request.Headers["X-File-Name"];

    if (fileName != null)
    {
        //string fileSize = Request.Headers["X-File-Size"];
        //string fileType = Request.Headers["X-File-Type"];
        //TODO...
         
        Request.SaveAs(Server.MapPath("/upload/") + fileName, false);
    }
}
%>
upload.asp:
<%@ Language="VBScript" %>
<%
Function Save (fileName, byteArray)
    on error resume next
    Dim  BinaryStream

    Set BinaryStream = CreateObject("ADODB.Stream")
   
    BinaryStream.Type = 1

    BinaryStream.Open
    BinaryStream.Write byteArray

    BinaryStream.SaveToFile Server.MapPath("upload") & "\" & fileName, 2
End Function

Dim strFileName
strFileName = Request.ServerVariables("HTTP_X-File-Name")

If (Len(strfileName) > 0) Then

    '... Request.ServerVariables("HTTP_X-File-Size")
    '... Request.ServerVariables("HTTP_X-File-Type")
    'TODO...

    Save strFileName, Request.BinaryRead(Request.TotalBytes)
End If
%>

4 comentarios:

  1. NO ME AYUDO EN NADA ESTE TUTORIAL, YA QUE YO NO USO ASPX, SINO PHP Y MYSQL

    ResponderEliminar
  2. sria excelente que explicara un minimo de funcionamiento del codigo como por ejemplo como implementarlo, que acciona la subida del archivo, el imput no tiene form, como lo envio? si no se explica nada el codigo pasa a ser esteril.

    ResponderEliminar
  3. edSystem, si hubiese leído todos los fragmentos de código te hubieses dado cuenta de que también se le da soporte a PHP. Además, no sé qué pinta MySQL en todo esto.

    ResponderEliminar
  4. tucarrodecompras, el formulario HTML no es necesario ya que se abre la solicitud mediante el objeto XMLHttpRequest con el método open y su primer parámetro 'POST'. Además, se especifica en el encabezado 'multipart/form-data' con el método setRequestHeader y, para terminar, se envían los bytes del archivo con el método send.

    ResponderEliminar