L'API WebHID permet aux sites Web d'accéder à d'autres claviers auxiliaires et à des manettes de jeu exotiques.
Il existe une longue liste de périphériques d'interface humaine (HID), tels que des claviers alternatifs ou des manettes de jeu exotiques, qui sont trop récents, trop anciens ou trop rares pour être accessibles par les pilotes de périphériques des systèmes. L'API WebHID résout ce problème en permettant d'implémenter une logique spécifique à l'appareil en JavaScript.
Cas d'utilisation suggérés
Un appareil HID reçoit des entrées ou fournit des sorties aux utilisateurs. Les claviers, les dispositifs de pointage (souris, écrans tactiles, etc.) et les manettes de jeu en sont des exemples. Le protocole HID permet d'accéder à ces appareils sur les ordinateurs de bureau à l'aide des pilotes du système d'exploitation. La plate-forme Web est compatible avec les appareils HID en s'appuyant sur ces pilotes.
L'impossibilité d'accéder aux périphériques HID peu courants est particulièrement problématique lorsqu'il s'agit de claviers auxiliaires alternatifs (par exemple, Elgato Stream Deck, casques Jabra, X-keys) et de la prise en charge des manettes de jeu exotiques. Les manettes de jeu conçues pour les ordinateurs de bureau utilisent souvent HID pour les entrées (boutons, joysticks, gâchettes) et les sorties (voyants, vibrations). Malheureusement, les entrées et sorties des manettes de jeu ne sont pas bien standardisées, et les navigateurs Web nécessitent souvent une logique personnalisée pour des appareils spécifiques. Cette approche n'est pas viable et entraîne une mauvaise prise en charge de la longue traîne des appareils anciens et peu courants. Il oblige également le navigateur à dépendre des particularités du comportement de certains appareils.
Terminologie
HID repose sur deux concepts fondamentaux : les rapports et les descripteurs de rapport. Les rapports sont les données échangées entre un appareil et un client logiciel. Le descripteur de rapport décrit le format et la signification des données compatibles avec l'appareil.
Un HID (Human Interface Device) est un type d'appareil qui reçoit des informations de l'utilisateur ou lui en fournit. Il fait également référence au protocole HID, une norme de communication bidirectionnelle entre un hôte et un appareil, conçue pour simplifier la procédure d'installation. Le protocole HID a été initialement développé pour les appareils USB, mais il a depuis été implémenté sur de nombreux autres protocoles, y compris Bluetooth.
Les applications et les appareils HID échangent des données binaires via trois types de rapports :
Type de rapport | Description |
---|---|
Rapport d'entrée | Données envoyées par l'appareil à l'application (par exemple, lorsqu'un bouton est enfoncé) |
Rapport de sortie | Données envoyées par l'application à l'appareil (par exemple, une demande d'allumer le rétroéclairage du clavier). |
Rapport sur les fonctionnalités | Données pouvant être envoyées dans les deux sens. Le format est spécifique à l'appareil. |
Un descripteur de rapport décrit le format binaire des rapports compatibles avec l'appareil. Sa structure est hiérarchique et peut regrouper des rapports sous forme de collections distinctes au sein de la collection de premier niveau. Le format du descripteur est défini par la spécification HID.
Une utilisation HID est une valeur numérique qui fait référence à une entrée ou une sortie standardisée. Les valeurs d'utilisation permettent à un appareil de décrire son utilisation prévue et l'objectif de chaque champ de ses rapports. Par exemple, un événement est défini pour le bouton gauche d'une souris. Les utilisations sont également organisées sur des pages d'utilisation, qui fournissent une indication de la catégorie générale de l'appareil ou du rapport.
Utiliser l'API WebHID
Détection de caractéristiques
Pour vérifier si l'API WebHID est compatible, utilisez le code suivant :
if ("hid" in navigator) {
// The WebHID API is supported.
}
Ouvrir une connexion HID
L'API WebHID est asynchrone par conception pour empêcher le blocage de l'UI du site Web lors de l'attente d'une entrée. Ceci est important, car les données HID peuvent être reçues à tout moment, ce qui nécessite un moyen de les écouter.
Pour ouvrir une connexion HID, accédez d'abord à un objet HIDDevice
. Pour ce faire, vous pouvez inviter l'utilisateur à sélectionner un appareil en appelant navigator.hid.requestDevice()
ou en en choisissant un dans navigator.hid.getDevices()
, qui renvoie une liste des appareils auxquels le site Web a déjà eu accès.
La fonction navigator.hid.requestDevice()
utilise un objet obligatoire qui définit les filtres. Ils permettent de faire correspondre n'importe quel appareil connecté avec un identifiant de fournisseur USB (vendorId
), un identifiant de produit USB (productId
), une valeur de page d'utilisation (usagePage
) et une valeur d'utilisation (usage
). Vous pouvez les obtenir à partir du dépôt d'ID USB et du document sur les tables d'utilisation HID.
Les multiples objets HIDDevice
renvoyés par cette fonction représentent plusieurs interfaces HID sur le même appareil physique.
// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
{
vendorId: 0x057e, // Nintendo Co., Ltd
productId: 0x2006 // Joy-Con Left
},
{
vendorId: 0x057e, // Nintendo Co., Ltd
productId: 0x2007 // Joy-Con Right
}
];
// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
// Get all devices the user has previously granted the website access to.
const devices = await navigator.hid.getDevices();

Vous pouvez également utiliser la clé exclusionFilters
facultative dans navigator.hid.requestDevice()
pour exclure certains appareils du sélecteur de navigateur qui sont connus pour mal fonctionner, par exemple.
// Request access to a device with vendor ID 0xABCD. The device must also have
// a collection with usage page Consumer (0x000C) and usage ID Consumer
// Control (0x0001). The device with product ID 0x1234 is malfunctioning.
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0xabcd, usagePage: 0x000c, usage: 0x0001 }],
exclusionFilters: [{ vendorId: 0xabcd, productId: 0x1234 }],
});
Un objet HIDDevice
contient des identifiants de fournisseur et de produit USB pour l'identification des appareils. Son attribut collections
est initialisé avec une description hiérarchique des formats de rapport de l'appareil.
for (let collection of device.collections) {
// An HID collection includes usage, usage page, reports, and subcollections.
console.log(`Usage: ${collection.usage}`);
console.log(`Usage page: ${collection.usagePage}`);
for (let inputReport of collection.inputReports) {
console.log(`Input report: ${inputReport.reportId}`);
// Loop through inputReport.items
}
for (let outputReport of collection.outputReports) {
console.log(`Output report: ${outputReport.reportId}`);
// Loop through outputReport.items
}
for (let featureReport of collection.featureReports) {
console.log(`Feature report: ${featureReport.reportId}`);
// Loop through featureReport.items
}
// Loop through subcollections with collection.children
}
Les appareils HIDDevice
sont renvoyés par défaut dans un état "fermé" et doivent être ouverts en appelant open()
avant que les données puissent être envoyées ou reçues.
// Wait for the HID connection to open before sending/receiving data.
await device.open();
Recevoir des rapports sur les entrées
Une fois la connexion HID établie, vous pouvez gérer les rapports d'entrée entrants en écoutant les événements "inputreport"
de l'appareil. Ces événements contiennent les données HID sous la forme d'un objet DataView
(data
), l'appareil HID auquel il appartient (device
) et l'ID de rapport de 8 bits associé au rapport d'entrée (reportId
).

En reprenant l'exemple précédent, le code ci-dessous vous montre comment détecter le bouton sur lequel l'utilisateur a appuyé sur un appareil Joy-Con Right afin que vous puissiez, espérons-le, l'essayer chez vous.
device.addEventListener("inputreport", event => {
const { data, device, reportId } = event;
// Handle only the Joy-Con Right device and a specific report ID.
if (device.productId !== 0x2007 && reportId !== 0x3f) return;
const value = data.getUint8(0);
if (value === 0) return;
const someButtons = { 1: "A", 2: "X", 4: "B", 8: "Y" };
console.log(`User pressed button ${someButtons[value]}.`);
});
Consultez la démo webhid-joycon-button.
Envoyer des rapports de sortie
Pour envoyer un rapport de sortie à un appareil HID, transmettez l'ID de rapport de 8 bits associé au rapport de sortie (reportId
) et les octets en tant que BufferSource
(data
) à device.sendReport()
. La promesse renvoyée est résolue une fois le signalement envoyé. Si le périphérique HID n'utilise pas d'ID de rapport, définissez reportId
sur 0.
L'exemple ci-dessous s'applique à un appareil Joy-Con et vous montre comment le faire vibrer avec des rapports de sortie.
// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));
// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample below.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));
Consultez la démo webhid-joycon-rumble.
Envoyer et recevoir des rapports sur les fonctionnalités
Les rapports de caractéristiques sont le seul type de rapports de données HID qui peuvent être transmis dans les deux sens. Ils permettent aux applications et appareils HID d'échanger des données HID non standardisées. Contrairement aux rapports d'entrée et de sortie, les rapports sur les fonctionnalités ne sont pas reçus ni envoyés régulièrement par l'application.

Pour envoyer un rapport de fonctionnalité à un appareil HID, transmettez l'ID de rapport de 8 bits associé au rapport de fonctionnalité (reportId
) et les octets en tant que BufferSource
(data
) à device.sendFeatureReport()
. La promesse renvoyée est résolue une fois le rapport envoyé. Si le périphérique HID n'utilise pas d'ID de rapport, définissez reportId
sur 0.
L'exemple ci-dessous illustre l'utilisation des rapports de caractéristiques en vous montrant comment demander un périphérique de rétroéclairage du clavier Apple, l'ouvrir et le faire clignoter.
const waitFor = duration => new Promise(r => setTimeout(r, duration));
// Prompt user to select an Apple Keyboard Backlight device.
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});
// Wait for the HID connection to open.
await device.open();
// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
// Turn off
await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
await waitFor(100);
// Turn on
await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
await waitFor(100);
}
Consultez la démo webhid-apple-keyboard-backlight.
Pour recevoir un rapport de fonctionnalité d'un appareil HID, transmettez l'ID de rapport de 8 bits associé au rapport de fonctionnalité (reportId
) à device.receiveFeatureReport()
. La promesse renvoyée est résolue avec un objet DataView
contenant le contenu du rapport sur les fonctionnalités. Si le périphérique HID n'utilise pas d'ID de rapport, définissez reportId
sur 0.
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
Écouter les événements de connexion et de déconnexion
Une fois que le site Web a été autorisé à accéder à un appareil HID, il peut recevoir activement des événements de connexion et de déconnexion en écoutant les événements "connect"
et "disconnect"
.
navigator.hid.addEventListener("connect", event => {
// Automatically open event.device or warn user a device is available.
});
navigator.hid.addEventListener("disconnect", event => {
// Remove |event.device| from the UI.
});
Révoquer l'accès à un appareil HID
Le site Web peut supprimer les autorisations d'accès à un appareil HID qu'il ne souhaite plus conserver en appelant forget()
sur l'instance HIDDevice
. Par exemple, pour une application Web éducative utilisée sur un ordinateur partagé avec de nombreux appareils, un grand nombre d'autorisations générées par les utilisateurs crée une mauvaise expérience utilisateur.
Si vous appelez forget()
sur une seule instance HIDDevice
, l'accès à toutes les interfaces HID sur le même appareil physique sera révoqué.
// Voluntarily revoke access to this HID device.
await device.forget();
Comme forget()
est disponible dans Chrome 100 ou version ultérieure, vérifiez si cette fonctionnalité est prise en charge en procédant comme suit :
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
Conseils pour les développeurs
Le débogage HID dans Chrome est facile grâce à la page interne about://device-log
, qui regroupe tous les événements liés aux appareils HID et USB.

Consultez l'explorateur HID pour afficher les informations sur les appareils HID dans un format lisible. Il mappe les valeurs d'utilisation sur les noms pour chaque utilisation HID.
Sur la plupart des systèmes Linux, les appareils HID sont mappés avec des autorisations en lecture seule par défaut. Pour autoriser Chrome à ouvrir un appareil HID, vous devez ajouter une règle udev. Créez un fichier à l'emplacement /etc/udev/rules.d/50-yourdevicename.rules
avec le contenu suivant :
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Dans la ligne ci-dessus, [yourdevicevendor]
est 057e
si votre appareil est un Joy-Con Nintendo Switch, par exemple. Vous pouvez également ajouter ATTRS{idProduct}
pour une règle plus spécifique. Assurez-vous que votre user
est membre du groupe plugdev
. Il vous suffit ensuite de reconnecter votre appareil.
Prise en charge des navigateurs
L'API WebHID est disponible sur toutes les plates-formes de bureau (ChromeOS, Linux, macOS et Windows) dans Chrome 89.
Démonstrations
Vous trouverez des démonstrations WebHID sur web.dev/hid-examples. Allez-y !
Sécurité et confidentialité
Les auteurs de la spécification ont conçu et implémenté l'API WebHID en utilisant les principes de base définis dans Controlling Access to Powerful Web Platform Features, y compris le contrôle utilisateur, la transparence et l'ergonomie. La possibilité d'utiliser cette API est principalement régie par un modèle d'autorisation qui n'accorde l'accès qu'à un seul périphérique HID à la fois. En réponse à une requête utilisateur, l'utilisateur doit effectuer des étapes actives pour sélectionner un appareil HID spécifique.
Pour comprendre les compromis en termes de sécurité, consultez la section Security and Privacy Considerations (Considérations sur la sécurité et la confidentialité) de la spécification WebHID.
De plus, Chrome inspecte l'utilisation de chaque collection de premier niveau. Si une collection de premier niveau a une utilisation protégée (par exemple, clavier générique, souris), un site Web ne pourra pas envoyer ni recevoir de rapports définis dans cette collection. La liste complète des utilisations protégées est disponible publiquement.
Notez que les appareils HID sensibles à la sécurité (tels que les appareils FIDO HID utilisés pour une authentification renforcée) sont également bloqués dans Chrome. Consultez les fichiers USB blocklist et HID blocklist.
Commentaires
L'équipe Chrome aimerait connaître votre avis et votre expérience concernant l'API WebHID.
Parlez-nous de la conception de l'API
Y a-t-il un élément de l'API qui ne fonctionne pas comme prévu ? Ou bien manquent-ils des méthodes ou des propriétés dont vous avez besoin pour mettre en œuvre votre idée ?
Signalez un problème de spécification dans le dépôt GitHub de l'API WebHID ou ajoutez vos commentaires à un problème existant.
Signaler un problème d'implémentation
Avez-vous trouvé un bug dans l'implémentation de Chrome ? Ou l'implémentation est-elle différente de la spécification ?
Consultez Comment signaler des bugs WebHID. Veillez à inclure autant de détails que possible, à fournir des instructions simples pour reproduire le bug et à définir Composants sur Blink>HID
.
Montrer votre soutien
Comptez-vous utiliser l'API WebHID ? Votre soutien public aide l'équipe Chrome à hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge.
Envoyez un tweet à @ChromiumDev avec le hashtag #WebHID
pour nous indiquer où et comment vous l'utilisez.
Liens utiles
- Spécification
- Bug de suivi
- Entrée ChromeStatus.com
- Composant Blink :
Blink>HID
Remerciements
Merci à Matt Reynolds et Joe Medley pour leurs commentaires sur cet article. Photo d'une Nintendo Switch rouge et bleue par Sara Kurfeß, et photo d'un ordinateur portable noir et argenté par Athul Cyriac Ajay sur Unsplash.