w3schools - formdata() javascript
¿Cómo enviar objetos FormData con peticiones Ajax en jQuery? (9)
Esta pregunta ya tiene una respuesta aquí:
- Enviando multipart / formdata con jQuery.ajax 12 respuestas
El estándar del Nivel 2 de XMLHttpRequest (aún un borrador en funcionamiento) define la interfaz FormData
. Esta interfaz permite agregar objetos de File
a solicitudes XHR (solicitudes Ajax).
Por cierto, esta es una nueva característica: en el pasado, se usaba el "truco de iframe oculto" (lea sobre esto en mi otra pregunta ).
Así es como funciona (ejemplo):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( ''file'', input.files[0] );
xhr.open( ''POST'', ''http://example.com/script.php'', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
donde input
es un campo <input type="file">
, y handler
es el controlador success para la solicitud Ajax.
Esto funciona a la perfección en todos los navegadores (de nuevo, excepto IE).
Ahora, me gustaría hacer que esta funcionalidad funcione con jQuery. Intenté esto:
var fd = new FormData();
fd.append( ''file'', input.files[0] );
$.post( ''http://example.com/script.php'', fd, handler );
Desafortunadamente, eso no funcionará (se produce un error de "invocación ilegal": la captura de pantalla está aquí ). Supongo que jQuery espera un simple objeto clave-valor que represente los nombres / valores de campos de formulario, y la instancia de FormData
que estoy transmitiendo es aparentemente incompatible.
Ahora, como es posible pasar una instancia de FormData
a xhr.send()
, espero que también sea posible hacer que funcione con jQuery.
Actualizar:
He creado un "ticket de función" en el Bug Tracker de jQuery. Está aquí: http://bugs.jquery.com/ticket/9995
Me sugirieron usar un "prefiltro Ajax" ...
Actualizar:
Primero, permítame presentar una demostración que demuestre qué comportamiento me gustaría lograr.
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( ''form'' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( ''file'', $( ''#file'' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( ''POST'', ''http://hacheck.tel.fer.hr/xml.pl'', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
El código anterior da como resultado esta solicitud HTTP:
Esto es lo que necesito , quiero ese tipo de contenido "multipart / form-data".
La solución propuesta sería así:
$( ''form'' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( ''file'', $( ''#file'' )[0].files[0] );
$.ajax({
url: ''http://hacheck.tel.fer.hr/xml.pl'',
data: data,
processData: false,
type: ''POST'',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
Sin embargo, esto resulta en:
Como puedes ver, el tipo de contenido es incorrecto ...
Creo que podrías hacerlo así:
var fd = new FormData();
fd.append( ''file'', input.files[0] );
$.ajax({
url: ''http://example.com/script.php'',
data: fd,
processData: false,
contentType: false,
type: ''POST'',
success: function(data){
alert(data);
}
});
Establecer processData
en falso le permite evitar que jQuery transforme automáticamente los datos en una cadena de consulta. Ver los documentos para más información.
Establecer el tipo de contentType
en falso es imprescindible, ya que de lo contrario jQuery lo configurará incorrectamente .
En lugar de - fd.append( ''userfile'', $(''#userfile'')[0].files[0]);
Use - fd.append( ''file'', $(''#userfile'')[0].files[0]);
Hay algunas técnicas aún por mencionar que están disponibles para usted. Comience con la configuración de la propiedad contentType en sus parámetros ajax.
Sobre la base del ejemplo de Pradeek:
$(''form'').submit(function (e) {
var data;
data = new FormData();
data.append(''file'', $(''#file'')[0].files[0]);
$.ajax({
url: ''http://hacheck.tel.fer.hr/xml.pl'',
data: data,
processData: false,
type: ''POST'',
// This will override the content type header,
// regardless of whether content is actually sent.
// Defaults to ''application/x-www-form-urlencoded''
contentType: ''multipart/form-data'',
//Before 1.5.1 you had to do this:
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
},
// Now you should be able to do this:
mimeType: ''multipart/form-data'', //Property added in 1.5.1
success: function (data) {
alert(data);
}
});
e.preventDefault();
});
En algunos casos, cuando se obliga a jQuery ajax a hacer cosas beforeSend
, el evento beforeSend
es un gran lugar para hacerlo. Durante un tiempo, las personas utilizaron beforeSend
de beforeSend
para reemplazar el mimeType antes de que se agregara a jQuery en 1.5.1. Debería poder modificar casi cualquier cosa en el objeto jqXHR en el evento anterior al envío.
JavaScript:
function submitForm() {
var data1 = new FormData($(''input[name^="file"]''));
$.each($(''input[name^="file"]'')[0].files, function(i, file) {
data1.append(i, file);
});
$.ajax({
url: "<?php echo base_url() ?>employee/dashboard2/test2",
type: "POST",
data: data1,
enctype: ''multipart/form-data'',
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;
}
PHP:
public function upload_file() {
foreach($_FILES as $key) {
$name = time().$key[''name''];
$path = ''upload/''.$name;
@move_uploaded_file($key[''tmp_name''], $path);
}
}
La mejor documentación y ejemplo que encontré estaba aquí https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects
Lo hago así y me funciona, espero que esto ayude :)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$(''#upload'').click(function(){
console.log(''upload button clicked!'')
var fd = new FormData();
fd.append( ''userfile'', $(''#userfile'')[0].files[0]);
$.ajax({
url: ''upload/do_upload'',
data: fd,
processData: false,
contentType: false,
type: ''POST'',
success: function(data){
console.log(''upload success!'')
$(''#data'').empty();
$(''#data'').append(data);
}
});
});
});
</script>
Puede enviar el objeto FormData en una solicitud ajax usando el siguiente código,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});
Esto es muy similar a la respuesta aceptada, pero es una respuesta real para el tema de la pregunta. Esto enviará los elementos del formulario automáticamente en FormData y no es necesario adjuntar manualmente los datos a la variable FormData.
El método ajax se ve así,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
//append some non-form data also
formData.append(''other_data'',$("#someInputData").val());
$.ajax({
type: "POST",
url: postDataUrl,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(data, textStatus, jqXHR) {
//process data
},
error: function(data, textStatus, jqXHR) {
//process error msg
},
});
También puede pasar manualmente el elemento de formulario dentro del objeto FormData como un parámetro como este
var formElem = $("#formId");
var formdata = new FormData(form[0]);
Espero eso ayude. ;)
Puede usar el evento $ .ajax beforeSend
para manipular el encabezado.
...
beforeSend: function(xhr) {
xhr.setRequestHeader(''Content-Type'', ''multipart/form-data'');
}
...
Consulte este enlace para obtener información adicional: http://msdn.microsoft.com/en-us/library/ms536752(v=vs.85).aspx
Si desea enviar archivos usando ajax use "jquery.form.js" Esto envía todos los elementos del formulario fácilmente.
Muestras http://jquery.malsup.com/form/#ajaxSubmit
vista aproximada:
<form id=''AddPhotoForm'' method=''post'' action=''../photo/admin_save_photo.php'' enctype=''multipart/form-data''>
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
information= responseText;
callAjaxtolist();
$("#AddPhotoForm").resetForm();
$("#photo_msg").html(''<div class="album_msg">Photo uploaded Successfully...</div>'');
};
$(document).ready(function(){
$(''.add_new_photo_div'').live(''click'',function(){
var options = {success:showResponseAfterAddPhoto};
$("#AddPhotoForm").ajaxSubmit(options);
});
});
</script>