Captura de captures de pantalla de DOM Elements: Server Side VS. Enfocaments del client

Fa unes setmanes, vaig escriure sobre Chatilyzer, un nou projecte secundari en el qual vaig estar treballant.

Una visió ràpida sobre l’aplicació i el flux de l’aplicació: Chatilyzer us permet obtenir estadístiques sobre els vostres xats de WhatsApp. Perquè l’aplicació funcioni, heu de penjar un fitxer * .txt exportat d’un xat de WhatsApp. Chatilyzer analitza i analitza el text i n’extreu algunes dades interessants. Aleshores, se us dirigeix ​​a una pàgina de resultats on veieu una bona visualització de l'activitat del vostre xat.

Un exemple de pàgina de resultats de Chatilyzer

Un dels reptes que tenia durant el desenvolupament d'aquesta aplicació web era permetre als usuaris crear una captura de pantalla de la pàgina de resultats i descarregar-la perquè poguessin compartir-la en el seu grup, en lloc de compartir una URL a la pàgina.

Enfocament del costat del servidor (NodeJS)

Vaig començar amb l'enfocament del servidor, utilitzant PhantomJS i un mòdul NPM anomenat "Node Webshot". Té una api molt senzilla que permet crear captures de pantalla a partir d’un URL determinat:

importar webshot des de "webshot";

webshot ("https://chatilyzer.com", "chat.png", funció (err) {
  // ara s’ha capturat la captura de pantalla a chat.png
});

Després de crear la captura de pantalla, vaig haver de penjar-la a un emmagatzematge en núvol i enviar de nou la URL de la imatge al costat del client per tal de permetre a l'usuari descarregar la imatge.

Pros:

  • Un mòdul a punt per utilitzar.
  • S'ha desat la captura de pantalla al núvol, de manera que estigui disponible en qualsevol moment.
  • Una aplicació flexible que us permet establir l'amplada i l'altura desitjades de la captura de pantalla.

Contres:

  • Tot o res: la captura de pantalla captura tota la pàgina i no podeu controlar cap element específic que vulgueu capturar.
  • Representació: si haureu d’esperar que es carregui l’async JS abans de capturar la captura de pantalla, és possible que tingueu problemes.
  • Medi ambient: tenint en compte que no es troba en un entorn real del navegador, PhantomJS no maneja les fonts personalitzades / Google tan adequades, cosa que comporta un tipus de lletra predeterminat que es mostra a la captura de pantalla.
  • Emmagatzematge: després de crear la captura de pantalla, heu de guardar-la en un emmagatzematge al núvol per tal de retornar una URL de imatge vàlida a l'usuari. Això vol dir que necessiteu un proveïdor d’emmagatzematge al núvol que possiblement us pugui costar més diners.
  • Seguretat: si les dades de la captura de pantalla són sensibles, guardar una còpia al núvol no és un bon enfocament.

EDIT: Després de rebre informació sobre la comunitat, resulta que hi ha una altra solució lateral del servidor mitjançant un mòdul NPM anomenat "Puppeteer" que es troba a la part superior de Chrome sense cap. Aquí es mostra com crear una captura de pantalla amb Puppeteer:

const puppeteer = require ('titellaire');

(async () => {
  const browser = waitp puppeteer.launch ();
  const page = espera browser.newPage ();
  espera page.goto ("https://chatilyzer.com");
  waitit page.screenshot ({path: 'chatilyzer.png'});

  espera browser.close ();
}) ();

Aquest mòdul resoldria els problemes de l'entorn, la renderització i l'entorn, ja que proporciona el mateix motor de renderització que Chrome.

Enfocament del costat del client

No he trobat el resultat del plantejament del costat del servidor prou bo per al meu cas d’ús, així que vaig començar a explorar altres opcions.

He trobat una biblioteca JS extremadament genial anomenada "html2canvas" que, com el seu nom indica, convertirà un element HTML en un element de tela.

lloc web html2canvas

Com podeu veure, també és molt fàcil d'utilitzar. Bàsicament, truqueu al mètode html2canvas i envieu un element DOM com a argument. Aquest mètode retorna una promesa que podeu utilitzar per extreure un element de tela.

html2canvas (document.querySelector ("# captura")), llavors (canvasElm => {
    document.body.appendChild (canvasElm);
});

A continuació, voleu habilitar el vostre usuari per descarregar la captura de pantalla.

La manera de fer-ho és mitjançant el mètode JS toDataURL com es pot veure a continuació:

// Obteniu una cadena de dades base64
var imageType = 'imatge / png';
var imageData = canvasElm.toDataURL (imageType);
// Obriu la cadena de dades a la finestra actual
document.location.href = imageData.replace (imageType, 'image / octet-stream');

Hi ha una altra biblioteca JS anomenada "canvas2image". Us recomano utilitzar-lo més aviat escrivint-lo per vosaltres mateixos, ja que proporciona més flexibilitat i també us permet generar una etiqueta d’imatge fora de l’element de la tela. Així podreu obtenir el mateix resultat mitjançant:

Canvas2Image.saveAsPNG (canvasElm, amplada, alçada);

Pros:

  • WYSIWYG: el resultat és el que veieu a la pantalla en 1: 1.
  • Sense costat del servidor: tot s’executa al navegador.
  • Seguretat: si les dades de la captura de pantalla són sensibles, capturar-les per part del client de manera molt més segura ja que el servidor no té coneixement dels resultats i no desa una còpia en un altre lloc.

Contres:

  • Compatibilitat - html2canvas no és compatible amb tots els navegadors
  • Costós: tot i que html2canvas retorna una promesa, no deixa de ser una acció cara i, per als components grans i complicats, pot trigar uns segons en obtenir resultats.
  • Vista estreta: si utilitzeu una pantalla estreta (per exemple, per a mòbils), la captura de pantalla serà estreta, a més de capturar la captura de pantalla de la vista real (que es pot resoldre passant una amplada de fixació com a argument a canvas2html o, obrint un iframe amb l'amplada desitjada en el fons, captura la captura de pantalla allà i envia de nou les dades de la imatge amb PostMessage).
  • Suport als elements: no tots els elements html són compatibles amb html2canvas. Per exemple, altres elements de tela, iframes i flash, no es mostraran en cap moment.

En conclusió

Hi ha dos enfocaments de com capturar una captura de pantalla d’elements html, i heu de pensar què s’adapta a les necessitats de l’aplicació.

L’enfocament del costat del servidor és el que trieu quan necessiteu una experiència de navegador / plataforma transversal i no esteu segurs que els vostres usuaris tinguin el navegador adequat per capturar la captura de pantalla. El preu que haureu de pagar és tant en el pagament físic del servei d’emmagatzematge en núvol com en resultats inexactes.

L’enfocament per part del client és bo quan s’assegura que els usuaris disposaran d’un navegador capaç de capturar la captura de pantalla (o que esteu preparat per pagar el preu per als que no ho són) i quan la precisió és imprescindible per a la captura de pantalla.

Pensament ràpid: suposo que el millor enfocament serà combinar entre ells. Podeu comprovar si la compatibilitat del navegador de l’usuari compta amb el suport que necessiteu per capturar una captura de pantalla i, si no, el mètode de recuperació del plantejament lateral.

Espero que us hagi agradat l’article. Aplaudeu que us hagi agradat :)

Coneixeu altres maneres de crear captures de pantalla de pàgines web amb NodeJS? Compartir en comentaris