POS e software

Lettore di codici a barre nelle applicazioni web: emulazione tastiera, WebHID, Web Serial e fotocamera

Nel browser un lettore in emulazione tastiera funziona senza codice aggiuntivo: scrive nel campo con il focus e, con il suffisso Invio, invia il modulo. Per letture senza focus puoi riconoscere il lettore dalla velocità delle battute. In alternativa, solo su browser basati su Chromium, WebHID e Web Serial leggono il dispositivo direttamente; con la fotocamera si usa BarcodeDetector o una libreria.

Quattro approcci a confronto

Modi di acquisire codici a barre in una web app
ApproccioModalità del lettoreBrowserQuando usarlo
Campo di input con focusHID tastieraTuttiModuli semplici, ricerca articolo
Ascolto globale della tastiera con rilevamento per tempiHID tastieraTuttiPagine senza un campo dedicato, cassa web
Web Serial APICOM virtuale o serialeChromium desktop (Chrome, Edge, Opera)Dati esatti, caratteri di controllo GS1
WebHID APIHID POS o HID non tastieraChromium desktopIntegrazioni avanzate, lettori in modalità HID POS
Fotocamera (BarcodeDetector o libreria JS)Nessun lettoreBarcodeDetector: supporto parziale, soprattutto Chromium su Android e macOSLetture saltuarie da smartphone

Safari e Firefox non supportano WebHID e Web Serial. Se la web app deve funzionare ovunque, la base resta l'emulazione tastiera; le API dirette sono un'aggiunta progressiva.

Il caso semplice: un campo che riceve il codice

Con il lettore impostato su emulazione tastiera e suffisso Invio, un <form> con un solo campo invia il codice a ogni lettura. Accorgimenti che evitano molti ticket:

  • metti l'autofocus sul campo e riportalo lì dopo ogni invio;
  • disattiva completamento automatico e correttore: autocomplete="off", autocorrect="off", spellcheck="false", perché i suggerimenti del browser possono intercettare l'Invio;
  • se il campo accetta solo cifre, non usare type="number": elimina gli zeri iniziali in alcuni passaggi e non accetta lettere; usa type="text" con inputmode="numeric";
  • gestisci l'Invio esplicitamente se il campo è in un modulo più grande, per evitare invii prematuri.

Se l'Invio non arriva, vedi lettore che non invia Invio; se arrivano simboli sbagliati, è il layout tastiera (caratteri sbagliati).

Rilevare il lettore dalla velocità delle battute

Un lettore digita molto più velocemente di una persona: tipicamente pochi millisecondi tra un carattere e l'altro, contro decine o centinaia per un umano. Puoi sfruttarlo per catturare le letture ovunque nella pagina:

let buffer = '';
let last = 0;
const MAX_GAP = 30;    // ms tra caratteri: da tarare sul tuo lettore
const MIN_LEN = 6;     // lunghezza minima di un codice valido

document.addEventListener('keydown', (e) => {
  const now = performance.now();
  if (now - last > MAX_GAP) buffer = '';   // pausa lunga: nuova sequenza
  last = now;

  if (e.key === 'Enter') {
    if (buffer.length >= MIN_LEN) {
      e.preventDefault();
      onScan(buffer);
    }
    buffer = '';
    return;
  }
  if (e.key.length === 1) buffer += e.key;  // ignora Shift, Ctrl, ecc.
});

function onScan(code) {
  console.log('Letto:', code);
}

Note pratiche:

  • misura il tuo lettore con il test del lettore, che mostra i tempi tra i caratteri, e tara la soglia; con lettori wireless o con ritardo tra caratteri attivo i tempi aumentano;
  • se l'utente sta scrivendo in un campo, decidi se lasciare passare i caratteri o bloccarli: il codice sopra li lascia arrivare anche al campo;
  • un'alternativa più robusta è configurare sul lettore un prefisso personalizzato raro come marcatore di inizio lettura.

e.key riflette il layout tastiera del sistema. Se lettore e sistema hanno layout diversi, i simboli arrivano trasformati anche nel tuo JavaScript: e.code dà la posizione fisica del tasto, ma non risolve il problema in modo generale. La soluzione resta allineare il layout (vedi impostare la tastiera italiana).

Web Serial: leggere un lettore in COM virtuale

Con il lettore in porta COM virtuale, la Web Serial API permette alla pagina di leggere i byte esatti, inclusi i separatori GS dei codici GS1. Richiede un contesto sicuro (HTTPS) e un gesto dell'utente per scegliere la porta:

button.addEventListener('click', async () => {
  const port = await navigator.serial.requestPort();
  await port.open({ baudRate: 9600 });
  const reader = port.readable.getReader();
  const dec = new TextDecoder();
  let buf = '';
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    buf += dec.decode(value);
    let i;
    while ((i = buf.indexOf('\r')) >= 0) {   // terminatore CR
      onScan(buf.slice(0, i));
      buf = buf.slice(i + 1).replace(/^\n/, '');
    }
  }
});

Il carattere GS arriva come \x1D: puoi passarlo alla tua logica o provare la stringa nel decodificatore GS1. Vedi anche carattere GS e FNC1.

WebHID: lettori in modalità HID POS

WebHID dà accesso a dispositivi HID che non sono tastiere, come i lettori in modalità HID POS. Il browser blocca l'accesso alle tastiere tramite WebHID, quindi non serve per un lettore in emulazione tastiera. Il formato dei report HID POS è definito dalle USB HID Usage Tables, ma i dettagli (report ID, posizione dei dati) vanno verificati sulla documentazione del lettore:

const [dev] = await navigator.hid.requestDevice({ filters: [] });
await dev.open();
dev.addEventListener('inputreport', (e) => {
  const bytes = new Uint8Array(e.data.buffer);
  console.log(e.reportId, bytes);   // interpreta secondo il manuale
});

Fotocamera: BarcodeDetector e alternative

L'API BarcodeDetector (Shape Detection API) decodifica codici da immagini o fotogrammi video. Il supporto è disomogeneo: verifica sempre la presenza dell'API e prevedi una libreria JavaScript come ripiego.

if ('BarcodeDetector' in window) {
  const formats = await BarcodeDetector.getSupportedFormats();
  const det = new BarcodeDetector({ formats: ['ean_13', 'qr_code', 'code_128'] });
  const codes = await det.detect(videoElement);
  codes.forEach(c => console.log(c.format, c.rawValue));
} else {
  // ripiego: libreria JS di decodifica
}

La fotocamera è comoda per letture occasionali, molto meno per volumi alti o etichette piccole. Puoi provare l'esperienza con il nostro lettore online con fotocamera e valutare il confronto in smartphone o lettore dedicato.

Errori comuni nelle web app

  • Zeri iniziali persi: il codice trattato come numero (in JavaScript o nel database). Conserva sempre i codici come stringhe.
  • Doppio invio: suffisso Invio sul lettore più invio automatico nello script. Scegli uno dei due.
  • Caratteri persi su pagine pesanti: handler lenti su input. Accumula nel buffer e lavora alla fine; vedi caratteri mancanti o letture doppie.
  • Codici con prefissi AIM (es. ]E0) arrivati per errore: vedi identificatore di simbologia AIM.

Fonti e riferimenti

  • W3C / WICG, specifiche Web Serial API, WebHID API e Shape Detection API (BarcodeDetector).
  • USB HID Usage Tables, pagine Keyboard/Keypad e Point of Sale.
  • Product Reference Guide dei lettori (modalità USB HID, CDC, HID POS): Zebra, Honeywell, Datalogic.

Altro in POS e software

Tutta la sezione POS e software