Tengo un problema al enviar un archivo a un script PHP del lado del servidor usando la función ajax de jQuery. Es posible obtener la Lista de archivos, $('#fileinput').attr('files')
pero ¿cómo es posible enviar estos Datos al servidor? La matriz resultante ( $_POST
) en el script php del lado del servidor es 0 ( NULL
) cuando se usa la entrada de archivo.
Sé que es posible (aunque no encontré ninguna solución de jQuery hasta ahora, solo el código Prototye ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ) )
Esto parece ser relativamente nuevo, así que no mencione que la carga de archivos sería imposible a través de XHR / Ajax, porque definitivamente funciona.
Necesito la funcionalidad en Safari 5, FF y Chrome sería bueno, pero no son esenciales.
Mi código por ahora es:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
$(':file')
para seleccionar todos los archivos de entrada. Es solo un poco más simple.Respuestas:
Comenzando con Safari 5 / Firefox 4, es más fácil usar la
FormData
clase:Entonces ahora tiene un
FormData
objeto, listo para ser enviado junto con XMLHttpRequest.Es imprescindible que establezca la
contentType
opciónfalse
, forzando a jQuery a no agregar unContent-Type
encabezado, de lo contrario, la cadena de límite no se incluirá. Además, debe dejar elprocessData
indicador establecido en falso, de lo contrario, jQuery intentará convertirloFormData
en una cadena, lo que fallará.Ahora puede recuperar el archivo en PHP usando:
(Solo hay un archivo, a
file-0
menos que haya especificado elmultiple
atributo en la entrada de su archivo, en cuyo caso, los números se incrementarán con cada archivo).Uso de la emulación FormData para navegadores antiguos
Crear FormData desde un formulario existente
En lugar de iterar manualmente los archivos, el objeto FormData también se puede crear con el contenido de un objeto de formulario existente:
Use una matriz nativa de PHP en lugar de un contador
Simplemente asigne a sus elementos de archivo el mismo nombre y termine el nombre entre paréntesis:
$_FILES['file']
entonces será una matriz que contiene los campos de carga de archivos para cada archivo cargado. De hecho, recomiendo esto sobre mi solución inicial, ya que es más simple iterar.fuente
data.fake
y establecer lacontentType
propiedad manualmente, así como anular xhr para usarsendAsBinary()
.jQuery
ni laFormData
clase y me preguntas en el contexto de una pregunta específica para jQuery y una respuesta específica para usar FormData? Lo siento, pero no creo que pueda ayudarte allí ...application/x-www-form-urlencoded
. ¿Hay alguna forma de usarmultipart/form-data
en su lugar?multipart/form-data
. Usarapplication/x-www-form-urlencoded
no funcionaría.Solo quería agregar un poco a la gran respuesta de Raphael. Aquí le mostramos cómo hacer que PHP produzca lo mismo
$_FILES
, independientemente de si usa JavaScript para enviar.Formulario HTML:
PHP produce esto
$_FILES
, cuando se envía sin JavaScript:Si realiza una mejora progresiva, utilice Raphael's JS para enviar los archivos ...
... así es
$_FILES
como se ve la matriz de PHP , después de usar ese JavaScript para enviar:Esa es una buena variedad, y en realidad es en lo que algunas personas se transforman
$_FILES
, pero creo que es útil trabajar con lo mismo$_FILES
, independientemente de si se usó JavaScript para enviar. Entonces, aquí hay algunos cambios menores al JS:(Edición del 14 de abril de 2017: eliminé el elemento de formulario del constructor de FormData (), que corrigió este código en Safari).
Ese código hace dos cosas.
input
atributo de nombre automáticamente, haciendo que el HTML sea más fácil de mantener. Ahora, siempre queform
la clase haya puesto imágenes, todo lo demás se encargará automáticamente. Es decir, lainput
necesidad no tiene ningún nombre especial.Con estos cambios, el envío con JavaScript ahora produce exactamente la misma
$_FILES
matriz que el envío con HTML simple.fuente
Mira mi código, hace el trabajo por mí
fuente
Acabo de construir esta función basada en alguna información que leí.
Utilizarlo como usar
.serialize()
, sólo hay que poner en su lugar.serializefiles();
.Trabajando aquí en mis pruebas.
fuente
var data = $("#avatar-form").serializefiles();
enviar esto a través del parámetro de datos ajax y analizar con formidable express:form.parse(req, function(err, fields, files){
gracias por ese fragmento de código :)Si su formulario está definido en su HTML, es más fácil pasar el formulario al constructor que iterar y agregar imágenes.
fuente
La respuesta de Devin Venable fue cercana a lo que quería, pero quería una que funcionara en múltiples formularios y utilizara la acción ya especificada en el formulario para que cada archivo vaya al lugar correcto.
También quería usar el método on () de jQuery para evitar usar .ready ().
Eso me llevó a esto: (reemplace formSelector con su selector jQuery)
fuente
Hoy en día ni siquiera necesita jQuery :) fetch API support table
fuente
fetch
, consulte compatibilidad: developer.mozilla.org/en-US/docs/Web/API/…:-|
La clase FormData funciona, sin embargo, en iOS Safari (al menos en el iPhone) no pude usar la solución de Raphael Schweikert tal como está.
Mozilla Dev tiene una buena página sobre la manipulación de objetos FormData .
Entonces, agregue un formulario vacío en algún lugar de su página, especificando el enctype:
Luego, cree el objeto FormData como:
y proceder como en el código de Raphael .
fuente
Creo que vale la pena señalar un problema que encontré hoy relacionado con este problema: si se redirige la url para la llamada ajax, entonces se puede perder el encabezado para content-type: 'multipart / form-data'.
Por ejemplo, estaba publicando en http://server.com/context?param=x
En la pestaña de red de Chrome, vi el encabezado multiparte correcto para esta solicitud, pero luego un redireccionamiento 302 a http://server.com/context/?param=x (tenga en cuenta la barra diagonal después del contexto)
Durante la redirección, se perdió el encabezado multiparte. Asegúrese de que las solicitudes no se redirijan si estas soluciones no funcionan para usted.
fuente
Todas las soluciones anteriores se ven bien y elegantes, pero el objeto FormData () no espera ningún parámetro, pero usa append () después de crear una instancia, como lo que se escribió anteriormente:
formData.append (val.name, val.value);
fuente
Si la entrada del archivo
name
indica una matriz y marcasmultiple
, y analiza todoform
conFormData
, no es necesario iterarappend()
los archivos de entrada.FormData
manejará automáticamente múltiples archivos.Tenga en cuenta que
button type="button"
se utiliza un regular , notype="submit"
. Esto muestra que no hay dependencia en el usosubmit
para obtener esta funcionalidad.La
$_FILES
entrada resultante es así en las herramientas de desarrollo de Chrome:Nota: Hay casos en que algunas imágenes se cargarán bien cuando se cargan como un solo archivo, pero fallarán cuando se carguen en un conjunto de múltiples archivos. El síntoma es que PHP informa vacío
$_POST
y$_FILES
sin que AJAX arroje ningún error. El problema ocurre con Chrome 75.0.3770.100 y PHP 7.0. Solo parece suceder con 1 de varias docenas de imágenes en mi conjunto de prueba.fuente
Las versiones anteriores de IE no son compatibles con FormData (la lista completa de compatibilidad del navegador para FormData está aquí: https://developer.mozilla.org/en-US/docs/Web/API/FormData ).
Puede usar un complemento jquery (por ejemplo, http://malsup.com/jquery/form/#code-samples ) o puede usar una solución basada en IFrame para publicar datos de formularios de varias partes a través de ajax: https: // developer. mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
fuente
PHP
jQuery y formulario HTML
fuente
fuente