Las capturas de pantalla de las aplicaciones web (o sitios web) son una forma bastante buena de arreglar errores de nuestros programas reportados por usuarios, ya que gracias a ellas podemos ver qué error aparece o cuál es el problema que reportan (sobre todo de diseño).
En el mundo de JavaScript existe la librería html2canvas cuyo uso ya vimos anteriormente, de hecho esto podría ser la continuación del mismo, en donde veremos cómo enviar una captura de pantalla a un servidor con PHP.
Aunque el ejemplo muestra cómo recibir la captura de la webapp con PHP, podemos adaptar el código para otros lenguajes del servidor.
Vamos a hacer una demostración para tomar una captura de una página web con html2canvas y después enviar la captura a un servidor con PHP.
Esta captura será enviada al hacer click en un botón, pero puede ser enviada incluso sin la acción del usuario (así que cuidado con los ataques XSS) en cualquier momento.
Puedes ver el código final y actualizado en mi GitHub. Por cierto, si quieres hacer esto con Node.JS ya he escrito el tutorial hace algún tiempo.
A través del post veremos muchas cosas que ya he explicado a fondo en otros lugares.
El post más importante es en donde usamos html2canvas para tomar una captura de una página web pero sin enviarla a ningún lado, sino adjuntarla o guardarla localmente.
Aparte de eso, en JavaScript utilizo las backticks y funciones flecha, codifico con JSON y finalmente en PHP lo decodifico para escribir el contenido en un archivo.
Por cierto, también te recomiendo ver el tutorial para tomar una foto de la cámara web con JavaScript y enviarla a PHP.
Nota: si no tienes PHP mira este post para instalarlo, o este otro en donde lo instalamos sobre Android.
Es un sitio web con una imagen, una tabla y algo de contenido.
<!DOCTYPE html>
<html>
<head>
<!--
* Tomar screenshot de página web con html2canvas para enviarla a un servidor
* web con PHP y guardarla como imagen
* Visita: https://parzibyte.me/blog
*
* @author parzibyte
-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Tomar captura de página web y enviarla a servidor web con PHP</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css" />
</head>
<body>
<!--
El botón no aparece porque está fuera del div
-->
<br>
<button class="button is-success" id="btnCapturar">Tomar captura</button>
<!--
En este caso le "tomamos" la foto al div. Podría ser a un div o
a cualquier elemento HTML
-->
<div id="contenedor">
<h1 class="is-size-1">Tomar captura de pantalla con html2canvas y enviarla a servidor web con PHP</h1>
<a href="//parzibyte.me/blog" target="_blank">By Parzibyte</a>
<div class="notification is-primary">
<p>Estamos probando la conversión de HTML a una imagen con html2canvas</p>
</div>
<table class="table is-bordered">
<thead>
<tr>
<th>Nombre</th>
<th>Versión</th>
</tr>
</thead>
<tbody>
<tr>
<td>KitKat</td>
<td>4.4</td>
</tr>
<tr>
<td>Lollipop</td>
<td>5</td>
</tr>
<tr>
<td>Marshmallow</td>
<td>6</td>
</tr>
<tr>
<td>Nougat</td>
<td>7</td>
</tr>
<tr>
<td>Oreo</td>
<td>8</td>
</tr>
<tr>
<td>Pie</td>
<td>9</td>
</tr>
</tbody>
</table>
<img style="max-width: 100%;" src="cosmos-4112660_1280.jpg">
</div>
<!--
Cargar el script de html2canvas, podría ser desde un servidor
propio o como yo lo hago: desde jsdelivr
-->
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.1/dist/html2canvas.min.js"></script>
<!--
Después de eso, cargar el script que contiene nuestra lógica
-->
<script src="script.js"></script>
</body>
</html>
En JavaScript le tomamos la foto al cuerpo completo; no ignoramos elementos ni capturamos otros elementos pero es totalmente posible como lo vimos en el post anterior.
La parte que cambia es que convertimos el canvas a imagen pero no la descargamos, sino que esa cadena en base 64 la enviamos a nuestro servidor usando AJAX a través de la función fetch
.
/**
* Tomar screenshot de página web con html2canvas para enviarla a un servidor
* web con PHP y guardarla como imagen
* Visita: https://parzibyte.me/blog
*
* @author parzibyte
*///Definimos el botón para escuchar su click
const $boton = document.querySelector("#btnCapturar"), // El botón que desencadena
$objetivo = document.body; // A qué le tomamos la foto
const enviarCapturaAServidor = canvas => {
// Cuando se resuelva la promesa traerá el canvas
// Convertir la imagen a Base64
let imagenComoBase64 = canvas.toDataURL();
// Codificarla, ya que a veces aparecen errores si no se hace
imagenComoBase64 = encodeURIComponent(imagenComoBase64);
// La carga útil como JSON
const payload = {
"captura": imagenComoBase64,
"by": "Parzibyte",
// Aquí más datos...
};
// Aquí la ruta en donde enviamos la foto. Podría ser una absoluta o relativa
const ruta = "./api/guardar.php";
fetch(ruta, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-type": "application/x-www-form-urlencoded",
}
})
.then(resultado => {
// A los datos los decodificamos como texto plano
return resultado.text()
})
.then(nombreDeLaFoto => {
// nombreDeLaFoto trae el nombre de la imagen que le dio PHP
console.log({ nombreDeLaFoto });
alert(`Guardada como ${nombreDeLaFoto}`);
});
};
// Agregar el listener al botón
$boton.addEventListener("click", () => {
html2canvas($objetivo) // Llamar a html2canvas y pasarle el elemento
.then(enviarCapturaAServidor); // Cuando se resuelva, enviarla al servidor
});
Si te fijas, he usado JSON para enviar los datos, ahí puedes adjuntar más datos si lo requieres.
En el lado del servidor accedemos al cuerpo de la petición y lo decodificamos con JSON.
Quitamos el “data/image…” de la imagen si es que lo tiene, decodificamos con urldecode
lo que codificamos con encodeURIComponent
, la imagen en base 64 la decodificamos igualmente y llamamos a file_put_contents para guardar la imagen.
<?php
/**
* Recibir screenshot tomada con html2canvas desde JavaScript
* Visita: https://parzibyte.me/blog
*
* @author parzibyte
*/
$payload = json_decode(file_get_contents("php://input"));
if (!$payload) {
exit("!No hay payload!");
}
$captura = $payload->captura;
$by = $payload->by;
// Aquí obtener más datos si existen...
// Quitar "data:image..." de la cadena
$capturaLimpia = str_replace("data:image/png;base64,", "", urldecode($captura));
//Venía codificada pero sólo la codificamos así para que viajara por la red,
//ahora la decodificamos y
//guardamos el contenido dentro de un archivo
$imagenDecodificada = base64_decode($capturaLimpia);
//Calcular un nombre único
// Nota: el nombre podría enviarse con la carga útil desde JS
$nombreImagenGuardada = "captura_" . uniqid() . ".png";
//Escribir el archivo
file_put_contents($nombreImagenGuardada, $imagenDecodificada);
echo $nombreImagenGuardada;
Finalmente imprimimos el nombre de la imagen guardada para que sea la respuesta que reciba JavaScript, y de nuevo lo digo, en la vida real podríamos enviar y recibir más cosas de acuerdo a las necesidades.
La combinación de JavaScript y PHP hace que nuestras apps tengan más funcionalidades sin importar su propósito.
En este ejemplo hemos visto cómo enviar una captura de pantalla a PHP, lo cual podríamos usar para recibir reportes de errores y ver exactamente lo que está pasando.
El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…
En este post te voy a enseñar a designar una carpeta para imprimir todos los…
En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…
Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…
Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…
Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…
Esta web usa cookies.
Ver comentarios
Hola, muy bueno tu tu tuorial, copié los archivos tal cual como está en GitHub pero no me funciona, no le he modificado nada, qué podría estar pasando.
Hola. Acabo de probar y funciona bien. Si tiene alguna duda puede enviarme un mensaje en https://parzibyte.me/#contacto