cómo hacer la carga de archivos usando la serialización jquery

81

Entonces tengo un formulario y estoy enviando el formulario a través de ajax usando la función de serialización jquery

        serialized = $(Forms).serialize();

        $.ajax({

        type        : "POST",
        cache   : false,
        url     : "blah",
        data        : serialized,
        success: function(data) {

        }

pero entonces, <input type="file">¿qué pasa si el formulario tiene un campo ... cómo paso el archivo al formulario usando este método de serialización ajax ... imprimir $ _FILES no genera nada

kamikaze_pilot
fuente

Respuestas:

53

No se puede cargar un archivo usando AJAX porque no puede acceder al contenido de un archivo almacenado en la computadora cliente y enviarlo en la solicitud usando javascript. Una de las técnicas para lograr esto es utilizar iframes ocultos. Hay un buen complemento de formulario jquery que le permite AJAXify sus formularios y también admite la carga de archivos . Entonces, al usar este complemento, su código simplemente se verá así:

$(function() {
    $('#ifoftheform').ajaxForm(function(result) {
        alert('the form was successfully processed');
    });
});

El complemento se encarga automáticamente de suscribirse al submitevento del formulario, cancelar el envío predeterminado, serializar los valores, utilizar el método adecuado y manejar los campos de carga de archivos, ...

Darin Dimitrov
fuente
42
Esto ya no es verdad. Con un <input type = 'file' name = 'myfile' /> y el objeto FormData (), uno puede guardar un archivo usando AJAX de manera muy simple. Vea la respuesta de Silver89 a continuación.
Rook777
1
@ Rook777, por supuesto, eso es cierto si el navegador que está utilizando es compatible con la API de archivos HTML5. ¿Has probado esto en IE, qué simple es? Hasta que HTML5 se convierta en un estándar y sea compatible con todos los navegadores, habrá complementos porque no puede cargar archivos usando AJAX.
Darin Dimitrov
2
Estás en lo correcto. Tengo la suerte de estar en un entorno de desarrollo que no es compatible con IE, así que me olvidé de considerarlo. Sí, sin compatibilidad con HTML5, esta función no funcionará. Según caniuse.com/xhr2 , solo IE 10+ admite esta función hasta ahora.
Rook777
¡El complemento jQuery Form es genial!
user1570144
48

FormDataObjeto de uso Funciona para cualquier tipo de formulario

$(document).on("submit", "form", function(event)
{
    event.preventDefault();
    $.ajax({
        url: $(this).attr("action"),
        type: $(this).attr("method"),
        dataType: "JSON",
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data, status)
        {

        },
        error: function (xhr, desc, err)
        {
            

        }
    });        

});
Islam Shaiful
fuente
23
   var form = $('#job-request-form')[0];
        var formData = new FormData(form);
        event.preventDefault();
        $.ajax({
            url: "/send_resume/", // the endpoint
            type: "POST", // http method
            processData: false,
            contentType: false,
            data: formData,

¡Funcionó para mí! simplemente establezca processData y contentType False.

Maryam Zakani
fuente
16

HTML

<form name="my_form" id="my_form" accept-charset="multipart/form-data" onsubmit="return false">
    <input id="name" name="name" placeholder="Enter Name" type="text" value="">
    <textarea id="detail" name="detail" placeholder="Enter Detail"></textarea>
    <select name="gender" id="gender">
        <option value="male" selected="selected">Male</option>
        <option value="female">Female</option>
    </select>
    <input type="file" id="my_images" name="my_images" multiple="" accept="image/x-png,image/gif,image/jpeg"/>
</form>

JavaScript

var data = new FormData();

//Form data
var form_data = $('#my_form').serializeArray();
$.each(form_data, function (key, input) {
    data.append(input.name, input.value);
});

//File data
var file_data = $('input[name="my_images"]')[0].files;
for (var i = 0; i < file_data.length; i++) {
    data.append("my_images[]", file_data[i]);
}

//Custom data
data.append('key', 'value');

$.ajax({
    url: "URL",
    method: "post",
    processData: false,
    contentType: false,
    data: data,
    success: function (data) {
        //success
    },
    error: function (e) {
        //error
    }
});

PHP

<?php
    echo '<pre>';
    print_r($_POST);
    print_r($_FILES);
    echo '</pre>';
    die();
?>
Renish Patel
fuente
¿Cómo enviar el nombre del botón de envío?
Muhammad Tarique
@MuhammadTarique Simplemente agregue el botón Me gusta <button type="button" name="button_name" value="Contact Button">Submit</button>y obtendrá la respuesta button_name = "Botón de contacto" en el lado de php
Renish Patel
Gracias por tu respuesta, pero no creo que funcione de esta manera. Sin embargo, ya hice esto usandoformData.append("btnName", "true");
Muhammad Tarique
@MuhammadTarique Este ejemplo ya se agregó en esta publicación comodata.append('key', 'value');
Renish Patel
11

Puede cargar archivos a través de AJAX utilizando el método FormData. Aunque IE7,8 y 9 no son compatibles con la funcionalidad FormData.

$.ajax({
    url: "ajax.php", 
    type: "POST",             
    data: new FormData('form'),
    contentType: false,       
    cache: false,             
    processData:false, 
    success: function(data) {
        $("#response").html(data);
    }
});
Rossco
fuente
qué es 'formulario' en el nuevo FormData ('formulario'), es la identificación, no funciona para mí
Mohamed Selim
Sí, normalmente sería el ID de formulario
Rossco
para mí, solo funciona con document.forms.form en lugar de la cadena 'form', pasada al constructor FormData
Mohamed Selim
10
$(document).on('click', '#submitBtn', function(e){
e.preventDefault();
e.stopImmediatePropagation();
var form = $("#myForm").closest("form");
var formData = new FormData(form[0]);
$.ajax({
    type: "POST",
    data: formData,
    dataType: "json",
    url: form.attr('action'),
    processData: false,
    contentType: false,
    success: function(data) {
         alert('Sucess! Form data posted with file type of input also!');
    }
)};});

Al hacer uso new FormData()y configurar el processData: false, contentType:falseenvío de la llamada ajax del formulario con la entrada del archivo funcionó para mí

Usando el código anterior, puedo enviar datos de formulario con el campo de archivo también a través de Ajax

RameshN
fuente
0

hmmmm, creo que hay una forma mucho más eficiente de hacerlo especialmente para las personas que desean apuntar a todos los navegadores y no solo a los navegadores compatibles con FormData

la idea de tener un IFRAME oculto en la página y hacer un envío normal para el ejemplo Desde dentro de IFrame

<FORM action='save_upload.php' method=post
   enctype='multipart/form-data' target=hidden_upload>
   <DIV><input
      type=file name='upload_scn' class=file_upload></DIV>
   <INPUT
      type=submit name=submit value=Upload /> <IFRAME id=hidden_upload
      name=hidden_upload src='' onLoad='uploadDone("hidden_upload")'
      style='width:0;height:0;border:0px solid #fff'></IFRAME> 
</FORM>

Lo más importante es hacer un objetivo de forma el ID de iframe oculto o el nombre y enctype multipart / form-data para permitir aceptar fotos

lado de javascript

function getFrameByName(name) {
    for (var i = 0; i < frames.length; i++)
        if (frames[i].name == name)
            return frames[i];

    return null;
}

function uploadDone(name) {
    var frame = getFrameByName(name);
    if (frame) {
        ret = frame.document.getElementsByTagName("body")[0].innerHTML;

        if (ret.length) {
            var json = JSON.parse(ret);
         // do what ever you want 
        }
    }
}

PHP de ejemplo del lado del servidor

<?php
  $target_filepath = "/tmp/" . basename($_FILES['upload_scn']['name']);

  if (move_uploaded_file($_FILES['upload_scn']['tmp_name'], $target_filepath)) {
    $result = ....
  }

echo json_encode($result);
?>
Jehad Ahmad Jaghoub
fuente
0

HTML5 presenta una FormDataclase que se puede usar para cargar archivos con ajax.

La compatibilidad con FormData comienza a partir de las siguientes versiones de los navegadores de escritorio. IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+

FormData - Mozilla.org

Rahul Patel
fuente