javascript - how - Subir imagen base64 con Ajax
save image base64 javascript (2)
Finalmente decidí convertir la imagen base64 en un Blob para que se pueda enviar a través de una solicitud Ajax con el objeto formData de la siguiente manera. Ahorra ancho de banda de carga (base64 toma un 33% más de bits que su equivalente binario) y no pude encontrar la razón para no transmitir el parámetro base64 (debido a la limitación de tamaño en algún lugar seguro).
La función base64ToBlob se basa en esta respuesta a otra pregunta .
function base64ToBlob(base64, mime)
{
mime = mime || '''';
var sliceSize = 1024;
var byteChars = window.atob(base64);
var byteArrays = [];
for (var offset = 0, len = byteChars.length; offset < len; offset += sliceSize) {
var slice = byteChars.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {type: mime});
}
Mi código JS:
var url = "url/action";
var image = $(''#image-id'').attr(''src'');
var base64ImageContent = image.replace(/^data:image//(png|jpg);base64,/, "");
var blob = base64ToBlob(base64ImageContent, ''image/png'');
var formData = new FormData();
formData.append(''picture'', blob);
$.ajax({
url: url,
type: "POST",
cache: false,
contentType: false,
processData: false,
data: formData})
.done(function(e){
alert(''done!'');
});
En Symfony2 puedo recuperar la imagen gracias a:
$picture = $request->files->get(''picture'');
Mi cliente ofrece al usuario elegir una imagen, recortarla y cambiar su tamaño y luego mostrarla (en un elemento DOM
<img>
).
Si la imagen está bien, el usuario puede subirla al servidor para que se pueda guardar.
Me gustaría hacer la carga gracias a una solicitud de Ajax.
Encontré toneladas de ejemplos en Internet para cargar la imagen original recuperada de la PC cliente. Por ejemplo:
$( ''#my-form'' )
.submit( function( e ) {
$.ajax( {
url: ''http://host.com/action/'',
type: ''POST'',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );
Esto funciona correctamente si decido cargar la imagen recuperada a través de la entrada del formulario.
En mi caso, quiero
cargar la imagen modificada
(guardada en un elemento
<img>
) en lugar de la original.
Esta imagen se almacena como una imagen base64 (para información: utilicé la biblioteca croppie.js para generar la imagen).
No sé cómo subir esta foto con Ajax.
Traté de cargarlo como un parámetro normal, pero en el lado del servidor, el img es una cadena vacía:
var url = ''http://host.com/action/'';
var data = {};
data.img = $(''img#generated-image'').attr(''src'');
$.ajax({url: url, type: "POST", data: data})
.done(function(e){
// Do something
});
// RESULTS in a empty data.img on the server side.
Mi problema es que el servidor tiene una cadena vacía al recuperar el parámetro "img". Sospecho que la imagen puede ser demasiado grande para pasarla al servidor u otros problemas que no entiendo ...
Así que me pregunto cuál es la forma correcta de enviar una imagen base64 al servidor utilizando una solicitud Ajax SIN utilizar un formulario.
Gracias por tu ayuda.
EDITAR
Parece ser un problema de tamaño de parámetro xmlHTTP POST. Traté de reducir el número de caracteres de la representación de cadena de la imagen y el servidor ahora puede recuperarla.
EDIT2
post_max_size se establece en 8M en el archivo php.ini cuando el tamaño de la imagen es de solo 24K.
Entonces el problema no está ahí.
Estoy usando PHP con el framework Symfony2.
Tal vez una limitación de Symfony2.
La respuesta de Nitseg funciona bien. Además, quería agregar las siguientes líneas si debe usar token de autenticación en su llamada ajax. Nuevamente, eche un vistazo a la respuesta de Nitseg para obtener más detalles primero.
var formData = new FormData();
var token = "<YOUR-TOKEN-HERE>";
formData.append("uploadfile", mediaBlob);
jQuery.ajax({
url: url,
type: "POST",
cache: false,
contentType: false,
processData: false,
data: formData,
beforeSend: function (xhr){
xhr.setRequestHeader("Authorization", "Bearer " + token);
}
})
.done((e) => {
// It is done.
})
.fail((e) => {
// Report that there is a problem!
});