Subir imagen desde un canvas al servidor en symfony.

Buen día/tarde/noche a la comunidad de libros web

Mis problemas son los siguientes:

Estoy trabajando en una aplicación hago presto un servicio de carnetizacion de usuarios, donde recibo datos de estos de una base de datos, sumado a eso tengo que tomarles una foto por medio de una webcam, la cual coloco en un canvas, lo que hago es enviar la foto en base64 en un textarea para que un controlador en php decodifique y guarde la imagen generada en el servidor.

Mi primer problema radica en que hay un conflicto con la ruta en la que envio los datos:

No route found for "POST /ud/carnet/enviarfoto/1136883231/'data%3Aimage/png%3Bbase64%2CBBBFBfj42Pj4'"

cuando la ruta que manejo es:

/ud/carnet/enviarfoto/{id}/{data}

Creo yo que hay problema por la / demas despues del png.

Aqui tengo el controlador de php que uso.

/**
     * @Route("/enviarfoto/{id}/{data}" , name="ud_carnet_foto", options={"expose"=true})
     * @Method("POST")
     */
    public function subirFotoAction($id,$data){
 
        /*if($request->isXmlHttpRequest() && !$request->isMethod('POST')){
            return new JsonResponse('XMLHttpRequests/AJAX calls must be POSTed', 404);
        }*/
 
        $imageData = substr($data, strpos($data, ",")+1);
 
        $foto = base64_decode($imageData);
 
        if(is_null($foto)){
            return new JsonResponse('No se ha subido el archivo', 404);
        }
 
        $em = $this->getDoctrine()->getManager();
 
        $consulta = $em->getRepository('AdminBundle:Usuarios')->find($id);
 
        $consulta->setFile($foto);
 
        $em->persist($consulta);
 
        $em->flush();
 
        return new JsonResponse('Imagen subida con exito',200);
    }

El script de jquery que uso:

$(document).ready(function(){
    $('#subir-foto').submit(function(event){
        var $id = $('#searchbox').val();
        var $data = $('#dataf').val();
        event.preventDefault();
        $.ajax({
            type: 'POST',
            url: Routing.generate('ud_carnet_foto', {'id': $id, 'data': $data}),
            data: {id: $id, data: $data},
            statusCode:{
                404: function(data){
                    alert(data);
                },
                500: function(){
                    alert('La peticion fallo');
                }
            }
        }).done(function(data){
            alert(data);
            $('#print').removeClass('hidden');
            $('.photo').addClass('hidden');
        });
    });
});

El fragmento de html que uso para enviar los datos

<form id="subir-foto">
   <div class="col-md-6">
   <textarea id="dataf" rows="4" cols="50" class="form-control" readonly="readonly" style="resize:none"></textarea>
 <br>
 <input id="upload" type="submit" class="btn btn-primary" />
</div>

El segundo problema ocurre cuando quiero enviar los datos de la imagen me genera un error 414, en el cual me dice que la URL es demasiado larga (la que pongo arriba es una ejemplo para probar), ¿hay algun metodo para que los datos de la imagen que envio desde el canvas sean mas cortos y poder enviarlos?

Muchas gracias de antemano por su ayuda

Respuestas

#1

El problema que veo en tu código es que estás usando un método POST de HTTTP como si fuera GET. La definición de tu ruta debería ser así:

/**
 * @Route("/enviarfoto" , name="ud_carnet_foto", options={"expose"=true})
 * @Method("POST")
 */

Los parámetros id y data no deben ir en la URL sino en el cuerpo de la petición HTTP, tal y como siempre se hace con las peticiones POST. La principal razón por la que se hace esto es precisamente el error que te está sucediendo: las URL tienen un límite de longitud y si incluyes los datos de una imagen en la URL, vas a superar ese límite ampliamente.

Después, en el controlador puedes acceder a las variables enviadas mediante POST con el siguiente código:

/**
 * @Route("/enviarfoto" , name="ud_carnet_foto", options={"expose"=true})
 * @Method("POST")
 */
public function subirFotoAction(Request $request)
{
    $id = $request->request->get('id');
    $data = $request->request->get('data');
 
    // ...
}
#2

Gracias @javiereguiluz por tu ayuda y perdón por la respuesta tardía.

Ahora tengo este error:

Catchable Fatal Error: Argument 1 passed to Proyecto\AdminBundle\Entity\Usuarios::setFile() must be an instance of Symfony\Component\HttpFoundation\File\UploadedFile, integer given, called in C:\xampp\htdocs\ProyectoUD2\src\Proyecto\CarnetBundle\Controller\DefaultController.php on line 143 and defined Como envió un string me genera el error.

¿Hay algún método para convertir el string en archivo y que el setFile lo pueda capturar correctamente en Symfony?