Carga de archivos sin formulario

95

Sin usar ningún formulario, ¿puedo simplemente enviar un archivo / archivos desde <input type="file">a 'upload.php' usando el método POST usando jQuery? La etiqueta de entrada no está dentro de ninguna etiqueta de formulario. Se coloca individualmente. Entonces no quiero usar complementos de jQuery como 'ajaxForm' o 'ajaxSubmit'.

Elo Peri
fuente
1
Prueba esto: uploadify.com pero usa la versión flash. Vamos, lanza tu piedra. No estoy seguro de si la versión HTML5 funciona sin un formulario. Probablemente lo hará, pero no estoy seguro.
Ismael Miguel
1
Arrr .... Quiero decir que debería funcionar en HTML 5. Pero va a estar plagado de problemas de compatibilidad de plataforma y navegadores de más de unos pocos años. ¿Cuál es el daño de crear una forma, o de generar dinámicamente una forma a partir de la red?
Yitzhak

Respuestas:

94

Puede utilizar FormData para enviar sus datos mediante una solicitud POST. He aquí un ejemplo sencillo:

var myFormData = new FormData();
myFormData.append('pictureFile', pictureInput.files[0]);

$.ajax({
  url: 'upload.php',
  type: 'POST',
  processData: false, // important
  contentType: false, // important
  dataType : 'json',
  data: myFormData
});

No tiene que usar un formulario para realizar una solicitud ajax, siempre que conozca la configuración de su solicitud (como la URL, el método y los datos de parámetros).

Omid Monshizadeh
fuente
En mi humilde opinión, esta es la mejor solución, sin embargo, otra opción es usar un <iframe dentro del que puede hacer una publicación regular
John Smith
Sí, eso es verdad. Los navegadores antiguos no admiten FormData y ajax para cargar archivos y la solución es usar iframe como respaldo en esos navegadores.
Omid Monshizadeh
7
No olvide agregar processData: falsey contentType: falseal objeto de configuración o, de lo contrario, recibirá Uncaught TypeError: Illegal invocation
jsmiff
2
¡¡Amigos, me salvasteis la vida !! : D Gracias @monshi y @ jsmiff. (La SOF no permite múltiples usuarios en el mismo comentario).
Silvio Delgado
4
¿Qué es pictureInput en esto?
developersaumya
30

Todas las respuestas aquí siguen usando la API FormData . Es como una "multipart/form-data"carga sin formulario. También puede cargar el archivo directamente como contenido dentro del cuerpo de la POSTsolicitud usando xmlHttpRequestasí:

var xmlHttpRequest = new XMLHttpRequest();

var file = ...file handle...
var fileName = ...file name...
var target = ...target...
var mimeType = ...mime type...

xmlHttpRequest.open('POST', target, true);
xmlHttpRequest.setRequestHeader('Content-Type', mimeType);
xmlHttpRequest.setRequestHeader('Content-Disposition', 'attachment; filename="' + fileName + '"');
xmlHttpRequest.send(file);

Content-Typey los Content-Dispositionencabezados se utilizan para explicar lo que estamos enviando (tipo mime y nombre de archivo).

Publiqué una respuesta similar también aquí .

Marchitar
fuente
1
Esta es una gran respuesta. Está evitando por completo el uso de datos de formulario. Puedo agregar un poco más al uso de xmlHttpRequest. Una XMLHttpRequest permite realizar operaciones asincrónicas, que no bloquean al cliente (página de interfaz de usuario). Al utilizar un formulario HTML, el cliente (página de interfaz de usuario) se bloquea mientras se realiza la operación.
Harry
¿Qué hay de fetch()?
Vitaly Zdanevich
@VitalyZdanevich ¿no estás seguro de lo que quieres decir con eso?
Marchita
13

Basándonos en este tutorial , aquí hay una forma muy básica de hacerlo:

$('your_trigger_element_selector').on('click', function(){    
    var data = new FormData();
    data.append('input_file_name', $('your_file_input_selector').prop('files')[0]);
    // append other variables to data if you want: data.append('field_name_x', field_value_x);

    $.ajax({
        type: 'POST',               
        processData: false, // important
        contentType: false, // important
        data: data,
        url: your_ajax_path,
        dataType : 'json',  
        // in PHP you can call and process file in the same way as if it was submitted from a form:
        // $_FILES['input_file_name']
        success: function(jsonData){
            ...
        }
        ...
    }); 
});

No olvide agregar el manejo de errores adecuado

Asombroso
fuente
11

Paso 1: Cree una página HTML donde colocar el código HTML.

Paso 2: En la parte inferior de la página de código HTML (pie de página), cree Javascript: y coloque el código Jquery en la etiqueta Script.

Paso 3: Crea un archivo PHP y copia el código php. después de Jquery Code in $.ajaxCode url, aplique cuál en su nombre de archivo php.

JS

//$(document).on("change", "#avatar", function() {   // If you want to upload without a submit button 
$(document).on("click", "#upload", function() {
  var file_data = $("#avatar").prop("files")[0]; // Getting the properties of file from file field
  var form_data = new FormData(); // Creating object of FormData class
  form_data.append("file", file_data) // Appending parameter named file with properties of file_field to form_data
  form_data.append("user_id", 123) // Adding extra parameters to form_data
  $.ajax({
    url: "/upload_avatar", // Upload Script
    dataType: 'script',
    cache: false,
    contentType: false,
    processData: false,
    data: form_data, // Setting the data attribute of ajax with file_data
    type: 'post',
    success: function(data) {
      // Do something after Ajax completes 
    }
  });
});

HTML

<input id="avatar" type="file" name="avatar" />
<button id="upload" value="Upload" />

Php

print_r($_FILES);
print_r($_POST);
Hadiyal Rakesh
fuente
1
Por favor, agregue algunos comentarios / descripción para su código
kvorobiev
falta un ,aftertype: 'post'
Rust
1
Me
alegró el
¿Puede cargar un archivo en un tmpdirectorio hasta que se envíe el formulario completo? (digamos que era una forma múltiple)?
thesayhey
¿Cómo referiré estas variables de formulario en el código java
Bhaskara Arani
1

Prueba este puglin simpleUpload , sin necesidad de formulario

HTML:

<input type="file" name="arquivo" id="simpleUpload" multiple >
<button type="button" id="enviar">Enviar</button>

Javascript:

$('#simpleUpload').simpleUpload({
  url: 'upload.php',
  trigger: '#enviar',
  success: function(data){
    alert('Envio com sucesso');

  }
});
Rodrigo Azevedo
fuente
1

Perdón por ser ese chico pero AngularJS ofrece una solución simple y elegante.

Aquí está el código que uso:

ngApp.controller('ngController', ['$upload',
function($upload) {

  $scope.Upload = function($files, index) {
    for (var i = 0; i < $files.length; i++) {
      var file = $files[i];
      $scope.upload = $upload.upload({
        file: file,
        url: '/File/Upload',
        data: {
          id: 1 //some data you want to send along with the file,
          name: 'ABC' //some data you want to send along with the file,
        },

      }).progress(function(evt) {

      }).success(function(data, status, headers, config) {
          alert('Upload done');
        }
      })
    .error(function(message) {
      alert('Upload failed');
    });
  }
};
}]);
.Hidden {
  display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div data-ng-controller="ngController">
  <input type="button" value="Browse" onclick="$(this).next().click();" />
  <input type="file" ng-file-select="Upload($files, 1)" class="Hidden" />
</div>

En el lado del servidor, tengo un controlador MVC con una acción que guarda los archivos cargados que se encuentran en la colección Request.Files y devuelve un JsonResult.

Si usa AngularJS, pruebe esto, si no lo hace ... lo siento amigo :-)

Shabi_669
fuente
Votado en contra porque no funciona con la directiva $ upload
NicoJuicy