jQuery Ajax File Upload

755

¿Puedo usar el siguiente código jQuery para realizar la carga de archivos usando el método POST de una solicitud ajax?

$.ajax({
    type: "POST",
    timeout: 50000,
    url: url,
    data: dataString,
    success: function (data) {
        alert('success');
        return false;
    }
});

Si es posible, ¿necesito llenar dataparte? ¿Es la forma correcta? Solo publico el archivo en el lado del servidor.

He estado buscando en Google, pero lo que encontré fue un complemento, mientras que en mi plan no quiero usarlo. Al menos por el momento.

Colita
fuente
Ajax no es compatible con la carga de archivos, debería usar iframe en su lugar
antyrat
1
Pregunta relacionada: stackoverflow.com/questions/6974684/…
Nathan Koop
2
Relacionado: stackoverflow.com/questions/166221/…
Timo Huovinen

Respuestas:

596

La carga de archivos no es posible a través de AJAX.
Puede cargar el archivo, sin actualizar la página utilizando IFrame.
Puede consultar más detalles aquí .


ACTUALIZAR

Con XHR2, se admite la carga de archivos a través de AJAX. Por ejemplo, a través del FormDataobjeto, pero desafortunadamente no es compatible con todos los navegadores antiguos.

FormData el soporte comienza desde las siguientes versiones de navegadores de escritorio.

  • IE 10+
  • Firefox 4.0+
  • Chrome 7+
  • Safari 5+
  • Opera 12+

Para más detalles, vea el enlace MDN .

Adeel
fuente
41
Aquí hay una lista de los navegadores específicos que no son compatibles: caniuse.com/#search=FormData También no lo he probado, pero aquí hay un polyfill para FormData gist.github.com/3120320
Ryan White
152
Específicamente, IE <10 no lo hace, para aquellos demasiado flojos para leer el enlace.
Kevin
22
@Synexis no, no tenemos que esperar tanto tiempo más porque todo IE solo tiene una cuota de mercado mundial del 22% y el 27% en los EE. UU. Y cae rápidamente. Lo más probable es que sean personas mayores de 70 años. Entonces, en lugar de que IE dicte lo que los desarrolladores tienen que hacer, IE tendrá que ponerse en forma o salir de la carrera.
Drew Calder
30
@DrewCalder La mayoría de los usuarios de IE son trabajadores de oficina que no tienen la opción de elegir qué navegador usar debido a las políticas de la compañía. No creo que la edad tenga mucho que ver con eso. Supongo que la mayoría de las personas> 70 obtienen su descendencia para instalar Chrome o FF en su lugar :)
Nicolas Connault
3
Este enlace realmente me ayudó a comprender lo mínimo. No tuve que usar una solicitud xhr. Si usa ajax, ¡asegúrese de configurarlo enctypeen "form/multipart"!
Luminoso
316

Iframes ya no es necesario para cargar archivos a través de ajax. Recientemente lo hice solo. Mira estas páginas:

Uso de cargas de archivos HTML5 con AJAX y jQuery

http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface

Actualicé la respuesta y la limpié. Use la función getSize para verificar el tamaño o use la función getType para verificar los tipos. Se agregó código de barra de progreso html y css.

var Upload = function (file) {
    this.file = file;
};

Upload.prototype.getType = function() {
    return this.file.type;
};
Upload.prototype.getSize = function() {
    return this.file.size;
};
Upload.prototype.getName = function() {
    return this.file.name;
};
Upload.prototype.doUpload = function () {
    var that = this;
    var formData = new FormData();

    // add assoc key values, this will be posts values
    formData.append("file", this.file, this.getName());
    formData.append("upload_file", true);

    $.ajax({
        type: "POST",
        url: "script",
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', that.progressHandling, false);
            }
            return myXhr;
        },
        success: function (data) {
            // your callback here
        },
        error: function (error) {
            // handle error
        },
        async: true,
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        timeout: 60000
    });
};

Upload.prototype.progressHandling = function (event) {
    var percent = 0;
    var position = event.loaded || event.position;
    var total = event.total;
    var progress_bar_id = "#progress-wrp";
    if (event.lengthComputable) {
        percent = Math.ceil(position / total * 100);
    }
    // update progressbars classes so it fits your code
    $(progress_bar_id + " .progress-bar").css("width", +percent + "%");
    $(progress_bar_id + " .status").text(percent + "%");
};

Cómo usar la clase Upload

//Change id to your id
$("#ingredient_file").on("change", function (e) {
    var file = $(this)[0].files[0];
    var upload = new Upload(file);

    // maby check size or type here with upload.getSize() and upload.getType()

    // execute upload
    upload.doUpload();
});

Código html de barra de progreso

<div id="progress-wrp">
    <div class="progress-bar"></div>
    <div class="status">0%</div>
</div>

Código css de barra de progreso

#progress-wrp {
  border: 1px solid #0099CC;
  padding: 1px;
  position: relative;
  height: 30px;
  border-radius: 3px;
  margin: 10px;
  text-align: left;
  background: #fff;
  box-shadow: inset 1px 3px 6px rgba(0, 0, 0, 0.12);
}

#progress-wrp .progress-bar {
  height: 100%;
  border-radius: 3px;
  background-color: #f39ac7;
  width: 0;
  box-shadow: inset 1px 1px 10px rgba(0, 0, 0, 0.11);
}

#progress-wrp .status {
  top: 3px;
  left: 50%;
  position: absolute;
  display: inline-block;
  color: #000000;
}
Ziinloader
fuente
3
Puede copiar más o menos el código directamente y usarlo. Simplemente cambie algunos nombres de identificación y nombres de clase. Cualquier personalización es tuya.
Ziinloader
44
Tenga en cuenta que myXhr parece ser global, así como su nombre, tamaño y tipo. También es mejor usar "beforeSend" para aumentar el objeto XMLHttpRequest ya creado en lugar de usar "xhr" para crear uno y luego cambiarlo.
Awatts
8
No creo que podamos usar eso como es @Ziinloader. Usted está utilizando algún método local que no está incluido: writer(catchFile). ¿Qué es writer()?
tandrewnichols
44
¿Qué sucede si los datos también contienen pocos campos junto con el archivo para cargar?
raju
2
@Ziinloader Este es un ejemplo tremendamente útil al que veo que has regresado y que has mantenido varias veces. Verdaderamente, una respuesta vale mucho más que el voto que puedo dar.
Regular Joe
191

La publicación de Ajax y el archivo de carga es posible. Estoy usando la jQuery $.ajaxfunción para cargar mis archivos. Traté de usar el objeto XHR pero no pude obtener resultados en el lado del servidor con PHP.

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);

$.ajax({
       url : 'upload.php',
       type : 'POST',
       data : formData,
       processData: false,  // tell jQuery not to process the data
       contentType: false,  // tell jQuery not to set contentType
       success : function(data) {
           console.log(data);
           alert(data);
       }
});

Como puede ver, debe crear un objeto FormData, vacío o desde (¿serializado? - $('#yourForm').serialize())formulario existente), y luego adjuntar el archivo de entrada.

Aquí hay más información: - Cómo cargar un archivo usando jQuery.ajax y FormData - Subiendo archivos a través de jQuery, se proporciona el objeto FormData y no hay nombre de archivo, solicitud GET

Para el proceso PHP puedes usar algo como esto:

//print_r($_FILES);
$fileName = $_FILES['file']['name'];
$fileType = $_FILES['file']['type'];
$fileError = $_FILES['file']['error'];
$fileContent = file_get_contents($_FILES['file']['tmp_name']);

if($fileError == UPLOAD_ERR_OK){
   //Processes your file here
}else{
   switch($fileError){
     case UPLOAD_ERR_INI_SIZE:   
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_FORM_SIZE:  
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_PARTIAL:    
          $message = 'Error: no terminó la acción de subir el archivo.';
          break;
     case UPLOAD_ERR_NO_FILE:    
          $message = 'Error: ningún archivo fue subido.';
          break;
     case UPLOAD_ERR_NO_TMP_DIR: 
          $message = 'Error: servidor no configurado para carga de archivos.';
          break;
     case UPLOAD_ERR_CANT_WRITE: 
          $message= 'Error: posible falla al grabar el archivo.';
          break;
     case  UPLOAD_ERR_EXTENSION: 
          $message = 'Error: carga de archivo no completada.';
          break;
     default: $message = 'Error: carga de archivo no completada.';
              break;
    }
      echo json_encode(array(
               'error' => true,
               'message' => $message
            ));
}
pedrozopayares
fuente
2
¿Qué biblioteca jquery necesito hacer referencia para ejecutar este código?
Rayden Black
La respuesta fue escrita en 2014. La versión de JQuery fue 1.10. No lo he probado con versiones más recientes.
pedrozopayares
55
formData.append('file', $('#file')[0].files[0]);regresa undefinedy console.log(formData) no tiene nada excepto_proto_
Yakob Ubaidi
1
No es compatible con IE 9, en caso de que alguno esté atrapado en el mismo infierno que yo
CountMurphy
3
Tengo esto para trabajar ... Pellizcame, estoy en jQuery Ajax file upload heaven! var formData = new FormData(); formData.append('file', document.getElementById('file').files[0]); $.ajax({ url : $("form[name='uploadPhoto']").attr("action"), type : 'POST', data : formData, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success : function(data) { console.log(data); alert(data); } });
TARKUS
104

Formulario de carga simple

 <script>
   //form Submit
   $("form").submit(function(evt){	 
      evt.preventDefault();
      var formData = new FormData($(this)[0]);
   $.ajax({
       url: 'fileUpload',
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
 });
</script>
<!--Upload Form-->
<form>
  <table>
    <tr>
      <td colspan="2">File Upload</td>
    </tr>
    <tr>
      <th>Select File </th>
      <td><input id="csv" name="csv" type="file" /></td>
    </tr>
    <tr>
      <td colspan="2">
        <input type="submit" value="submit"/> 
      </td>
    </tr>
  </table>
</form>

vickisys
fuente
señor, ¿cuáles son los js que se usaron en este ejemplo? Hay un plugin jquery específico para este ... tengo una pregunta que me señalaron aquí, ¿pueden verificar mi pregunta? Quiero cargar múltiples archivos o imágenes en ese proyecto aquí es el enlace stackoverflow.com/questions/28644200/…
Brownman Revival
19
$ (esto) [0] es esto
machineaddict
2
¿Cuál es el parámetro en el servidor para el archivo publicado? ¿Puedes por favor publicar parte del servidor?
FrenkyB
@FrenkyB y otros - los archivos en el servidor (en PHP) no se almacenan en la variable $ _POST - se almacenan en la variable $ _FILES. En este caso, accedería a él con $ _FILES ["csv"] porque "csv" es el atributo de nombre de la etiqueta de entrada.
dev_masta
68

Llegué bastante tarde a esto, pero estaba buscando una solución de carga de imágenes basada en ajax y la respuesta que estaba buscando estaba un poco dispersa en esta publicación. La solución que decidí involucraba el objeto FormData. Reuní una forma básica del código que armé. Puede ver que muestra cómo agregar un campo personalizado al formulario con fd.append () y cómo manejar los datos de respuesta cuando se realiza la solicitud ajax.

Subir html:

<!DOCTYPE html>
<html>
<head>
    <title>Image Upload Form</title>
    <script src="//code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
        function submitForm() {
            console.log("submit event");
            var fd = new FormData(document.getElementById("fileinfo"));
            fd.append("label", "WEBUPLOAD");
            $.ajax({
              url: "upload.php",
              type: "POST",
              data: fd,
              processData: false,  // tell jQuery not to process the data
              contentType: false   // tell jQuery not to set contentType
            }).done(function( data ) {
                console.log("PHP Output:");
                console.log( data );
            });
            return false;
        }
    </script>
</head>

<body>
    <form method="post" id="fileinfo" name="fileinfo" onsubmit="return submitForm();">
        <label>Select a file:</label><br>
        <input type="file" name="file" required />
        <input type="submit" value="Upload" />
    </form>
    <div id="output"></div>
</body>
</html>

En caso de que esté trabajando con php, aquí hay una forma de manejar la carga que incluye el uso de los dos campos personalizados que se muestran en el html anterior.

Upload.php

<?php
if ($_POST["label"]) {
    $label = $_POST["label"];
}
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 200000)
&& in_array($extension, $allowedExts)) {
    if ($_FILES["file"]["error"] > 0) {
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    } else {
        $filename = $label.$_FILES["file"]["name"];
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";

        if (file_exists("uploads/" . $filename)) {
            echo $filename . " already exists. ";
        } else {
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "uploads/" . $filename);
            echo "Stored in: " . "uploads/" . $filename;
        }
    }
} else {
    echo "Invalid file";
}
?>
lee8oi
fuente
que estoy recibiendo Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https,por qué es esto, señor, así que copiar y pegar el código, ya que es
Brownman Revival
2
@HogRider: si Google envía su mensaje de error, este es el primer resultado: stackoverflow.com/questions/10752055/… ¿Está accediendo a sus páginas web localmente file://, en lugar de utilizar un servidor web? Por otro lado, no es la mejor práctica simplemente copiar y pegar código a ciegas sin primero entenderlo. Te recomendaría que revises el código línea por línea para comprender lo que está sucediendo antes de usar el código.
Colincameron
@colincameron gracias por aclarar algunas cosas que revisé línea por línea y realmente no entiendo mucho, así que hice la pregunta para que alguien pueda aclarar mis dudas. Estoy usando local por cierto xampp para ser exactos. ¿Puedo hacer una pregunta que quizás puedas aclarar?
Brownman Revival
@Brownman Revival: Sé que es demasiado tarde para la respuesta. Recibió un error de origen cruzado porque abrió el archivo html como archivo que lo ejecutó desde el servidor.
Adarsh ​​Mohan
@AdarshMohan Aprecio la respuesta, ¿cómo sugieres que lo haga para hacerlo bien?
Brownman Revival
31

Una carga AJAX es realmente posible con XMLHttpRequest() . No hay iframes necesarios. Se puede mostrar el progreso de carga.

Para obtener más información, consulte: Responda https://stackoverflow.com/a/4943774/873282 a la pregunta jQuery Upload Progress y AJAX file upload .

koppor
fuente
24
Lamentablemente, IE <10 no es compatible con esto.
Sasha Chedygov
1
Cuando simplemente desea referirse a otra página como respuesta, puede votar para cerrar como dupkucate o dejar un comentario debajo de la pregunta. Esta publicación no es una respuesta. Una publicación de este tipo parece un intento de cultivar representante.
mickmackusa
18

Así es como lo hice funcionar:

HTML

<input type="file" id="file">
<button id='process-file-button'>Process</button>

JS

$('#process-file-button').on('click', function (e) {
    let files = new FormData(), // you can consider this as 'data bag'
        url = 'yourUrl';

    files.append('fileName', $('#file')[0].files[0]); // append selected file to the bag named 'file'

    $.ajax({
        type: 'post',
        url: url,
        processData: false,
        contentType: false,
        data: files,
        success: function (response) {
            console.log(response);
        },
        error: function (err) {
            console.log(err);
        }
    });
});

PHP

if (isset($_FILES) && !empty($_FILES)) {
    $file = $_FILES['fileName'];
    $name = $file['name'];
    $path = $file['tmp_name'];


    // process your file

}
М.Б.
fuente
2
Lo que más me ayudó sobre esto fue $('#file')[0].files[0]que es una especie de solución extraña de JS sin requerir una adecuada<form>
ffgpga08
Esta es la solución completa, el bit PHP también ayuda.
cdsaenz
14

En caso de que quieras hacerlo así:

$.upload( form.action, new FormData( myForm))
.progress( function( progressEvent, upload) {
    if( progressEvent.lengthComputable) {
        var percent = Math.round( progressEvent.loaded * 100 / progressEvent.total) + '%';
        if( upload) {
            console.log( percent + ' uploaded');
        } else {
            console.log( percent + ' downloaded');
        }
    }
})
.done( function() {
    console.log( 'Finished upload');                    
});

que

https://github.com/lgersman/jquery.orangevolt-ampere/blob/master/src/jquery.upload.js

Podría ser tu solución.

Lgersman
fuente
¿Dónde está el método de carga de $ objeto, el enlace de arriba es que no existen
coolesting
2
Gracias por publicar tu respuesta! Asegúrese de leer atentamente las preguntas frecuentes sobre autopromoción. También tenga en cuenta que es necesario que publique un descargo de responsabilidad cada vez que enlace a su propio sitio / producto.
Andrew Barber
13
  • Use un iframe oculto y establezca el objetivo de su formulario con el nombre de ese iframe. De esta manera, cuando se envía el formulario, solo se actualizará el iframe.
  • Tener un controlador de eventos registrado para el evento de carga del iframe para analizar la respuesta.

Más detalles en mi blog: http://blog.manki.in/2011/08/ajax-fie-upload.html .

Manki
fuente
Evite los iframes cuando sea posible
Bhargav Nanekalva
@BhargavNanekalva, ¿cuál es tu preocupación?
aswzen
13
$("#submit_car").click( function() {
  var formData = new FormData($('#car_cost_form')[0]);
$.ajax({
       url: 'car_costs.php',
       data: formData,
       async: false,
       contentType: false,
       processData: false,
       cache: false,
       type: 'POST',
       success: function(data)
       {
       },
     })    return false;    
});

editar: Tenga en cuenta el tipo de contenido y los datos de proceso. Simplemente puede usar esto para cargar archivos a través de Ajax ...... la entrada de envío no puede estar fuera del elemento de formulario :)

Gvice
fuente
3
Con este método, puede publicar formularios pero no con campos de tipo 'archivo'. Esta pregunta es específicamente sobre la carga de archivos.
Jomy John
11

Actualización 2019:

html

<form class="fr" method='POST' enctype="multipart/form-data"> {% csrf_token %}
<textarea name='text'>
<input name='example_image'>
<button type="submit">
</form>

js

$(document).on('submit', '.fr', function(){

    $.ajax({ 
        type: 'post', 
        url: url, <--- you insert proper URL path to call your views.py function here.
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        data: new FormData(this) ,
        success: function(data) {
             console.log(data);
        }
        });
        return false;

    });

views.py

form = ThisForm(request.POST, request.FILES)

if form.is_valid():
    text = form.cleaned_data.get("text")
    example_image = request.FILES['example_image']
Arrendajo
fuente
1
¿Cómo mejora esto alguna de las respuestas ya dadas? Además, esta respuesta menciona un archivo views.py que es Django y no tiene nada que ver con la pregunta.
dirkgroten
66
Debido a que el problema se manifiesta de manera comparable mientras usa Django, y si está usando Django, no hay mucha dirección aquí en lo que respecta a resolverlo. Pensé que ofrecería asistencia proactiva en caso de que alguien llegue aquí como lo hice en el futuro. ¿Tienes un día difícil?
Jay
9

Use FormData. Funciona muy bien :-) ...

var jform = new FormData();
jform.append('user',$('#user').val());
jform.append('image',$('#image').get(0).files[0]); // Here's the important bit

$.ajax({
    url: '/your-form-processing-page-url-here',
    type: 'POST',
    data: jform,
    dataType: 'json',
    mimeType: 'multipart/form-data', // this too
    contentType: false,
    cache: false,
    processData: false,
    success: function(data, status, jqXHR){
        alert('Hooray! All is well.');
        console.log(data);
        console.log(status);
        console.log(jqXHR);

    },
    error: function(jqXHR,status,error){
        // Hopefully we should never reach here
        console.log(jqXHR);
        console.log(status);
        console.log(error);
    }
});
delboy1978uk
fuente
esto es lo que: ('usuario', $ ('# usuario'). val ());
rahim.nagori
cuadro de texto con id = "usuario" se adjunta al formulario @ rahim.nagori
Alp Altunel
1
Un enfoque más directo: var jform = new FormData ($ ('form'). Get (0));
André Morales hace
bien, gracias, lo intentaré la próxima vez que use FormData
delboy1978uk
7

He implementado una selección de archivos múltiples con vista previa instantánea y carga después de eliminar archivos no deseados de la vista previa a través de ajax.

La documentación detallada se puede encontrar aquí: http://anasthecoder.blogspot.ae/2014/12/multi-file-select-preview-without.html

Demostración: http://jsfiddle.net/anas/6v8Kz/7/embedded/result/

jsFiddle: http://jsfiddle.net/anas/6v8Kz/7/

Javascript:

    $(document).ready(function(){
    $('form').submit(function(ev){
        $('.overlay').show();
        $(window).scrollTop(0);
        return upload_images_selected(ev, ev.target);
    })
})
function add_new_file_uploader(addBtn) {
    var currentRow = $(addBtn).parent().parent();
    var newRow = $(currentRow).clone();
    $(newRow).find('.previewImage, .imagePreviewTable').hide();
    $(newRow).find('.removeButton').show();
    $(newRow).find('table.imagePreviewTable').find('tr').remove();
    $(newRow).find('input.multipleImageFileInput').val('');
    $(addBtn).parent().parent().parent().append(newRow);
}

function remove_file_uploader(removeBtn) {
    $(removeBtn).parent().parent().remove();
}

function show_image_preview(file_selector) {
    //files selected using current file selector
    var files = file_selector.files;
    //Container of image previews
    var imageContainer = $(file_selector).next('table.imagePreviewTable');
    //Number of images selected
    var number_of_images = files.length;
    //Build image preview row
    var imagePreviewRow = $('<tr class="imagePreviewRow_0"><td valign=top style="width: 510px;"></td>' +
        '<td valign=top><input type="button" value="X" title="Remove Image" class="removeImageButton" imageIndex="0" onclick="remove_selected_image(this)" /></td>' +
        '</tr> ');
    //Add image preview row
    $(imageContainer).html(imagePreviewRow);
    if (number_of_images > 1) {
        for (var i =1; i<number_of_images; i++) {
            /**
             *Generate class name of the respective image container appending index of selected images, 
             *sothat we can match images selected and the one which is previewed
             */
            var newImagePreviewRow = $(imagePreviewRow).clone().removeClass('imagePreviewRow_0').addClass('imagePreviewRow_'+i);
            $(newImagePreviewRow).find('input[type="button"]').attr('imageIndex', i);
            $(imageContainer).append(newImagePreviewRow);
        }
    }
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        /**
         * Allow only images
         */
        var imageType = /image.*/;
        if (!file.type.match(imageType)) {
          continue;
        }

        /**
         * Create an image dom object dynamically
         */
        var img = document.createElement("img");

        /**
         * Get preview area of the image
         */
        var preview = $(imageContainer).find('tr.imagePreviewRow_'+i).find('td:first');

        /**
         * Append preview of selected image to the corresponding container
         */
        preview.append(img); 

        /**
         * Set style of appended preview(Can be done via css also)
         */
        preview.find('img').addClass('previewImage').css({'max-width': '500px', 'max-height': '500px'});

        /**
         * Initialize file reader
         */
        var reader = new FileReader();
        /**
         * Onload event of file reader assign target image to the preview
         */
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        /**
         * Initiate read
         */
        reader.readAsDataURL(file);
    }
    /**
     * Show preview
     */
    $(imageContainer).show();
}

function remove_selected_image(close_button)
{
    /**
     * Remove this image from preview
     */
    var imageIndex = $(close_button).attr('imageindex');
    $(close_button).parents('.imagePreviewRow_' + imageIndex).remove();
}

function upload_images_selected(event, formObj)
{
    event.preventDefault();
    //Get number of images
    var imageCount = $('.previewImage').length;
    //Get all multi select inputs
    var fileInputs = document.querySelectorAll('.multipleImageFileInput');
    //Url where the image is to be uploaded
    var url= "/upload-directory/";
    //Get number of inputs
    var number_of_inputs = $(fileInputs).length; 
    var inputCount = 0;

    //Iterate through each file selector input
    $(fileInputs).each(function(index, input){

        fileList = input.files;
        // Create a new FormData object.
        var formData = new FormData();
        //Extra parameters can be added to the form data object
        formData.append('bulk_upload', '1');
        formData.append('username', $('input[name="username"]').val());
        //Iterate throug each images selected by each file selector and find if the image is present in the preview
        for (var i = 0; i < fileList.length; i++) {
            if ($(input).next('.imagePreviewTable').find('.imagePreviewRow_'+i).length != 0) {
                var file = fileList[i];
                // Check the file type.
                if (!file.type.match('image.*')) {
                    continue;
                }
                // Add the file to the request.
                formData.append('image_uploader_multiple[' +(inputCount++)+ ']', file, file.name);
            }
        }
        // Set up the request.
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.onload = function () {
            if (xhr.status === 200) {
                var jsonResponse = JSON.parse(xhr.responseText);
                if (jsonResponse.status == 1) {
                    $(jsonResponse.file_info).each(function(){
                        //Iterate through response and find data corresponding to each file uploaded
                        var uploaded_file_name = this.original;
                        var saved_file_name = this.target;
                        var file_name_input = '<input type="hidden" class="image_name" name="image_names[]" value="' +saved_file_name+ '" />';
                        file_info_container.append(file_name_input);

                        imageCount--;
                    })
                    //Decrement count of inputs to find all images selected by all multi select are uploaded
                    number_of_inputs--;
                    if(number_of_inputs == 0) {
                        //All images selected by each file selector is uploaded
                        //Do necessary acteion post upload
                        $('.overlay').hide();
                    }
                } else {
                    if (typeof jsonResponse.error_field_name != 'undefined') {
                        //Do appropriate error action
                    } else {
                        alert(jsonResponse.message);
                    }
                    $('.overlay').hide();
                    event.preventDefault();
                    return false;
                }
            } else {
                /*alert('Something went wrong!');*/
                $('.overlay').hide();
                event.preventDefault();
            }
        };
        xhr.send(formData);
    })

    return false;
}
Ima
fuente
@Bhargav: Consulte la publicación del blog para obtener explicaciones: goo.gl/umgFFy . Si todavía tiene alguna pregunta, contácteme Gracias
Ima
7

Los he manejado en un código simple. Puede descargar una demostración funcional desde aquí

Para su caso, estos muy posibles. Le explicaré paso a paso cómo puede cargar un archivo en el servidor utilizando AJAX jquery.

Primero, creemos un archivo HTML para agregar el siguiente elemento de archivo de formulario como se muestra a continuación.

<form action="" id="formContent" method="post" enctype="multipart/form-data" >
         <input  type="file" name="file"  required id="upload">
         <button class="submitI" >Upload Image</button> 
</form>

En segundo lugar, cree un archivo jquery.js y agregue el siguiente código para manejar nuestro envío de archivos al servidor

    $("#formContent").submit(function(e){
        e.preventDefault();

    var formdata = new FormData(this);

        $.ajax({
            url: "ajax_upload_image.php",
            type: "POST",
            data: formdata,
            mimeTypes:"multipart/form-data",
            contentType: false,
            cache: false,
            processData: false,
            success: function(){
                alert("file successfully submitted");
            },error: function(){
                alert("okey");
            }
         });
      });
    });

Ahí estás listo. Ver más

Daniel Nyamasyo
fuente
7

Usar FormData es el camino a seguir, como lo indican muchas respuestas. Aquí hay un poco de código que funciona muy bien para este propósito. También estoy de acuerdo con el comentario de anidar bloques ajax para completar circunstancias complejas. Al incluir e.PreventDefault (); en mi experiencia hace que el código sea más compatible con varios navegadores.

    $('#UploadB1').click(function(e){        
    e.preventDefault();

    if (!fileupload.valid()) {
        return false;            
    }

    var myformData = new FormData();        
    myformData.append('file', $('#uploadFile')[0].files[0]);

    $("#UpdateMessage5").html("Uploading file ....");
    $("#UpdateMessage5").css("background","url(../include/images/loaderIcon.gif) no-repeat right");

    myformData.append('mode', 'fileUpload');
    myformData.append('myid', $('#myid').val());
    myformData.append('type', $('#fileType').val());
    //formData.append('myfile', file, file.name); 

    $.ajax({
        url: 'include/fetch.php',
        method: 'post',
        processData: false,
        contentType: false,
        cache: false,
        data: myformData,
        enctype: 'multipart/form-data',
        success: function(response){
            $("#UpdateMessage5").html(response); //.delay(2000).hide(1); 
            $("#UpdateMessage5").css("background","");

            console.log("file successfully submitted");
        },error: function(){
            console.log("not okay");
        }
    });
});
Mike Volmar
fuente
esto ejecuta el formulario a través de jquery validate ... if (! fileupload.valid ()) {return false; }
Mike Volmar
7

Usar js puro es más fácil

async function saveFile(inp) 
{
    let formData = new FormData();           
    formData.append("file", inp.files[0]);
    await fetch('/upload/somedata', {method: "POST", body: formData});    
    alert('success');
}
<input type="file" onchange="saveFile(this)" >

  • En el lado del servidor, puede leer el nombre del archivo original (y otra información) que se incluye automáticamente para solicitar.
  • NO necesita configurar el encabezado "Content-Type" en el navegador "multipart / form-data", lo configurará automáticamente
  • Estas soluciones deberían funcionar en todos los principales navegadores.

Aquí hay un fragmento más desarrollado con manejo de errores y envío adicional de json

Kamil Kiełczewski
fuente
6

Sí, puede, solo use javascript para obtener el archivo, asegurándose de leer el archivo como una URL de datos. Analice las cosas antes de base64 para obtener los datos codificados de base 64 y luego, si está usando php o realmente cualquier lenguaje de fondo, puede decodificar los datos de base 64 y guardarlos en un archivo como se muestra a continuación

Javascript:
var reader = new FileReader();
reader.onloadend = function ()
{
  dataToBeSent = reader.result.split("base64,")[1];
  $.post(url, {data:dataToBeSent});
}
reader.readAsDataURL(this.files[0]);


PHP:
    file_put_contents('my.pdf', base64_decode($_POST["data"]));

Por supuesto, es probable que desee hacer alguna validación, como verificar qué tipo de archivo está tratando y cosas así, pero esta es la idea.

Piacenti
fuente
file_put_contents ($ fname, file_get_contents ($ _ POST ['data'])); file_get_contents se ocupa de la decodificación y los datos: // header
Nande
5
<html>
    <head>
        <title>Ajax file upload</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function (e) {
            $("#uploadimage").on('submit', (function(e) {
            e.preventDefault();
                    $.ajax({
                    url: "upload.php", // Url to which the request is send
                            type: "POST", // Type of request to be send, called as method
                            data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
                            contentType: false, // The content type used when sending data to the server.
                            cache: false, // To unable request pages to be cached
                            processData:false, // To send DOMDocument or non processed data file it is set to false
                            success: function(data)   // A function to be called if request succeeds
                            {
                            alert(data);
                            }
                    });
            }));
        </script>
    </head>
    <body>
        <div class="main">
            <h1>Ajax Image Upload</h1><br/>
            <hr>
            <form id="uploadimage" action="" method="post" enctype="multipart/form-data">
                <div id="image_preview"><img id="previewing" src="noimage.png" /></div>
                <hr id="line">
                <div id="selectImage">
                    <label>Select Your Image</label><br/>
                    <input type="file" name="file" id="file" required />
                    <input type="submit" value="Upload" class="submit" />
                </div>
            </form>
        </div>
    </body>
</html>
Nikit Barochiya
fuente
4

Puede usar el método ajaxSubmit como sigue :) cuando selecciona un archivo que necesita cargarse en el servidor, envíe el formulario al servidor :)

$(document).ready(function () {
    var options = {
    target: '#output',   // target element(s) to be updated with server response
    timeout: 30000,
    error: function (jqXHR, textStatus) {
            $('#output').html('have any error');
            return false;
        }
    },
    success: afterSuccess,  // post-submit callback
    resetForm: true
            // reset the form after successful submit
};

$('#idOfInputFile').on('change', function () {
    $('#idOfForm').ajaxSubmit(options);
    // always return false to prevent standard browser submit and page navigation
    return false;
});
});
Quy Le
fuente
2
Creo que estás hablando del complemento jquery form . Realmente es la mejor opción aquí, aparte de la falta de detalles en su respuesta.
fotanus
@fotanus tienes razón! ese script debe usar el complemento de formulario jquery para enviar el método de uso ajaxSubmit que define en el complemento de formulario jquery
Quy Le
4

Para cargar un archivo enviado por el usuario como parte del formulario utilizando jquery, siga el código siguiente:

var formData = new FormData();
formData.append("userfile", fileInputElement.files[0]);

Luego envíe el objeto de datos del formulario al servidor.

También podemos agregar un archivo o blob directamente al objeto FormData.

data.append("myfile", myBlob, "filename.txt");
VISHNU Radhakrishnan
fuente
3

Si desea cargar un archivo usando AJAX, aquí hay un código que puede usar para cargar archivos.

$(document).ready(function() {
    var options = { 
                beforeSubmit:  showRequest,
        success:       showResponse,
        dataType: 'json' 
        }; 
    $('body').delegate('#image','change', function(){
        $('#upload').ajaxForm(options).submit();        
    }); 
});     
function showRequest(formData, jqForm, options) { 
    $("#validation-errors").hide().empty();
    $("#output").css('display','none');
    return true; 
} 
function showResponse(response, statusText, xhr, $form)  { 
    if(response.success == false)
    {
        var arr = response.errors;
        $.each(arr, function(index, value)
        {
            if (value.length != 0)
            {
                $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
            }
        });
        $("#validation-errors").show();
    } else {
         $("#output").html("<img src='"+response.file+"' />");
         $("#output").css('display','block');
    }
}

Aquí está el HTML para cargar el archivo

<form class="form-horizontal" id="upload" enctype="multipart/form-data" method="post" action="upload/image'" autocomplete="off">
    <input type="file" name="image" id="image" /> 
</form>
Nikunj K.
fuente
3

Para obtener todas sus entradas de formulario, incluido el tipo = "archivo" , debe usar el objeto FormData . podrá ver el contenido de formData en el depurador -> red -> Encabezados después de enviar el formulario.

var url = "YOUR_URL";

var form = $('#YOUR_FORM_ID')[0];
var formData = new FormData(form);


$.ajax(url, {
    method: 'post',
    processData: false,
    contentType: false,
    data: formData
}).done(function(data){
    if (data.success){ 
        alert("Files uploaded");
    } else {
        alert("Error while uploading the files");
    }
}).fail(function(data){
    console.log(data);
    alert("Error while uploading the files");
});
David
fuente
2
var dataform = new FormData($("#myform")[0]);
//console.log(dataform);
$.ajax({
    url: 'url',
    type: 'POST',
    data: dataform,
    async: false,
    success: function(res) {
        response data;
    },
    cache: false,
    contentType: false,
    processData: false
});
Jayesh Paunikar
fuente
55
puede mejorar su respuesta agregando algunos detalles
SR
1

Aquí había una idea en la que estaba pensando:

Have an iframe on page and have a referencer.

Tenga una forma en la que mueva el elemento INPUT: File a.

Form:  A processing page AND a target of the FRAME.

El resultado se publicará en el marco, y luego puede enviar los datos recuperados un nivel a la etiqueta de imagen que desee con algo como:

data:image/png;base64,asdfasdfasdfasdfa

y la página se carga.

Creo que funciona para mí, y dependiendo de que pueda hacer algo como:

.aftersubmit(function(){
    stopPropigation()// or some other code which would prevent a refresh.
});
Fallenreaper
fuente
No veo cómo esto mejora ninguna otra respuesta dada anteriormente. ¡También es propagación, no propagación! ;)
JDuarteDJ