WebHID API, web sitelerinin alternatif yardımcı klavyelere ve sıra dışı gamepad'lere erişmesine olanak tanır.
Alternatif klavyeler veya egzotik gamepad'ler gibi, sistemlerin cihaz sürücüleri tarafından erişilemeyecek kadar yeni, eski veya nadir olan çok sayıda insan arayüz cihazı (HID) vardır. WebHID API, cihaza özel mantığı JavaScript'te uygulamanın bir yolunu sağlayarak bu sorunu çözer.
Önerilen kullanım alanları
HID cihaz, insanlardan giriş alır veya insanlara çıkış sağlar. Cihaz örnekleri arasında klavyeler, işaretleme cihazları (fareler, dokunmatik ekranlar vb.) ve gamepad'ler yer alır. HID protokolü, işletim sistemi sürücülerini kullanarak masaüstü bilgisayarlarda bu cihazlara erişmeyi mümkün kılar. Web platformu, bu sürücüleri kullanarak HID cihazlarını destekler.
Alternatif yardımcı klavyeler (ör. Elgato Stream Deck, Jabra kulaklıklar, X-keys) ve egzotik gamepad desteği söz konusu olduğunda, yaygın olmayan HID cihazlara erişememek özellikle can sıkıcıdır. Masaüstü için tasarlanan oyun kumandaları, oyun kumandası girişleri (düğmeler, kontrol çubukları, tetikler) ve çıkışları (LED'ler, titreşim) için genellikle HID'yi kullanır. Maalesef gamepad giriş ve çıkışları iyi bir şekilde standartlaştırılmamıştır ve web tarayıcılar genellikle belirli cihazlar için özel mantık gerektirir. Bu durum sürdürülebilir değildir ve daha eski ve yaygın olmayan cihazların uzun kuyruğu için yetersiz destek sunulmasına neden olur. Bu durum, tarayıcının belirli cihazların davranışındaki tuhaflıklara bağlı olmasına da neden olur.
Terminoloji
HID iki temel kavramdan oluşur: raporlar ve rapor tanımlayıcıları. Raporlar, bir cihaz ile bir yazılım istemcisi arasında değiştirilen verilerdir. Rapor tanımlayıcısı, cihazın desteklediği verilerin biçimini ve anlamını açıklar.
HID (İnsan Arabirim Cihazı), insanlardan giriş alan veya insanlara çıkış sağlayan bir cihaz türüdür. Ayrıca, kurulum prosedürünü basitleştirmek için tasarlanmış bir ana makine ile bir cihaz arasında çift yönlü iletişimin standardı olan HID protokolünü de ifade eder. HID protokolü başlangıçta USB cihazlar için geliştirilmiş olsa da o zamandan beri Bluetooth da dahil olmak üzere birçok başka protokolde uygulanmıştır.
Uygulamalar ve HID cihazları, üç rapor türü aracılığıyla ikili verileri değiştirir:
Rapor türü | Açıklama |
---|---|
Giriş raporu | Cihazdan uygulamaya gönderilen veriler (ör. bir düğmeye basılması) |
Çıkış raporu | Uygulamadan cihaza gönderilen veriler (ör. klavye arka ışığını açma isteği) |
Özellik raporu | İki yönde de gönderilebilen veriler. Biçim cihaza özeldir. |
Rapor tanımlayıcısı, cihaz tarafından desteklenen raporların ikili biçimini tanımlar. Yapısı hiyerarşiktir ve raporları üst düzey koleksiyonda ayrı koleksiyonlar olarak gruplandırabilir. Tanımlayıcının biçimi HID spesifikasyonu tarafından tanımlanır.
HID kullanımı, standartlaştırılmış bir girişi veya çıkışı ifade eden sayısal bir değerdir. Kullanım değerleri, bir cihazın kullanım amacını ve raporlarındaki her alanın amacını tanımlamasına olanak tanır. Örneğin, farenin sol düğmesi için bir tane tanımlanır. Kullanımlar, cihazın veya raporun üst düzey kategorisi hakkında bilgi veren kullanım sayfalarında da düzenlenir.
WebHID API'yi kullanma
Özellik algılama
WebHID API'nin desteklenip desteklenmediğini kontrol etmek için şunu kullanın:
if ("hid" in navigator) {
// The WebHID API is supported.
}
HID bağlantısı açma
WebHID API, web sitesi kullanıcı arayüzünün giriş beklenirken engellenmesini önlemek için tasarımdan dolayı eşzamansızdır. HID verileri herhangi bir zamanda alınabildiğinden ve dinlenmesi gerektiğinden bu önemlidir.
Bir HID bağlantısı açmak için önce bir HIDDevice
nesnesine erişin. Bunun için kullanıcıdan navigator.hid.requestDevice()
işlevini çağırarak bir cihaz seçmesini isteyebilir veya navigator.hid.getDevices()
işlevinden bir cihaz seçebilirsiniz. Bu işlev, web sitesine daha önce erişim izni verilen cihazların listesini döndürür.
navigator.hid.requestDevice()
işlevi, filtreleri tanımlayan zorunlu bir nesne alır. Bunlar, USB tedarikçi tanımlayıcısı (vendorId
), USB ürün tanımlayıcısı (productId
), kullanım sayfası değeri (usagePage
) ve kullanım değeri (usage
) ile bağlı cihazları eşleştirmek için kullanılır. Bu değerleri USB ID Repository ve HID kullanım tabloları dokümanından alabilirsiniz.
Bu işlev tarafından döndürülen birden fazla HIDDevice
nesnesi, aynı fiziksel cihazdaki birden fazla HID arayüzünü temsil eder.
// 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();

Ayrıca, bazı cihazları (ör. arızalı olduğu bilinenler) tarayıcı seçiciden hariç tutmak için exclusionFilters
anahtarını navigator.hid.requestDevice()
içinde kullanabilirsiniz.
// 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 }],
});
HIDDevice
nesnesi, cihaz tanımlama için USB tedarikçi ve ürün tanımlayıcılarını içerir. collections
özelliği, cihazın rapor biçimlerinin hiyerarşik bir açıklamasıyla başlatılır.
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
}
HIDDevice
cihazlar varsayılan olarak "kapalı" durumda iade edilir ve veri gönderilip alınabilmesi için open()
numarası aranarak açılması gerekir.
// Wait for the HID connection to open before sending/receiving data.
await device.open();
Giriş raporları alma
HID bağlantısı kurulduktan sonra, cihazdan gelen "inputreport"
etkinliklerini dinleyerek gelen giriş raporlarını işleyebilirsiniz. Bu etkinlikler; HID verilerini DataView
nesnesi (data
), ait olduğu HID cihazı (device
) ve giriş raporuyla ilişkili 8 bitlik rapor kimliği (reportId
) olarak içerir.

Önceki örnekten devam edersek aşağıdaki kod, Joy-Con Right cihazında kullanıcının hangi düğmeye bastığını nasıl tespit edeceğinizi gösterir. Böylece, umarız bu kodu evde deneyebilirsiniz.
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]}.`);
});
Pen webhid-joycon-button demosuna bakın.
Çıkış raporları gönderme
Bir çıkış raporunu HID cihazına göndermek için çıkış raporuyla ilişkili 8 bitlik rapor kimliğini (reportId
) ve baytları BufferSource
(data
) olarak device.sendReport()
'a iletin. Döndürülen söz, rapor gönderildikten sonra çözümlenir. HID cihazı rapor kimliklerini kullanmıyorsa reportId
değerini 0 olarak ayarlayın.
Aşağıdaki örnek, Joy-Con cihazı için geçerlidir ve çıkış raporlarıyla nasıl titreşim oluşturacağınızı gösterir.
// 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));
webhid-joycon-rumble demosuna göz atın.
Özellik raporları gönderme ve alma
Özellik raporları, her iki yönde de aktarılabilen tek HID veri raporu türüdür. HID cihazlarının ve uygulamalarının standartlaştırılmamış HID verilerini değiştirmesine olanak tanır. Giriş ve çıkış raporlarının aksine, özellik raporları uygulama tarafından düzenli olarak alınmaz veya gönderilmez.

Bir özellik raporunu HID cihazına göndermek için özellik raporuyla (reportId
) ilişkili 8 bitlik rapor kimliğini ve baytları BufferSource
(data
) olarak device.sendFeatureReport()
'a iletin. Döndürülen söz, rapor gönderildikten sonra çözümlenir. HID cihazı rapor kimliklerini kullanmıyorsa reportId
değerini 0 olarak ayarlayın.
Aşağıdaki örnekte, Apple klavye arka ışığı cihazı isteğinde bulunma, cihazı açma ve yanıp söndürme işlemlerinin nasıl yapılacağı gösterilerek özellik raporlarının kullanımı açıklanmaktadır.
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);
}
Pen webhid-apple-keyboard-backlight demosuna göz atın.
Bir HID cihazından özellik raporu almak için özellik raporuyla (reportId
) ilişkili 8 bitlik rapor kimliğini device.receiveFeatureReport()
'ye iletin. Döndürülen söz, özellik raporunun içeriğini içeren bir DataView
nesnesiyle çözümlenir. HID cihazı rapor kimliklerini kullanmıyorsa reportId
değerini 0 olarak ayarlayın.
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
Bağlantı ve bağlantı kesme işlemlerini dinleme
Bir web sitesine HID cihazına erişme izni verildiğinde, "connect"
ve "disconnect"
etkinliklerini dinleyerek bağlantı ve bağlantı kesme etkinliklerini aktif olarak alabilir.
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.
});
HID cihazına erişimi iptal etme
Web sitesi, HIDDevice
örneğinde forget()
işlevini çağırarak artık tutmak istemediği HID cihazlara erişim izinlerini temizleyebilir. Örneğin, birçok cihazla paylaşılan bir bilgisayarda kullanılan bir eğitim web uygulamasında, kullanıcı tarafından oluşturulan çok sayıda izin birikmesi kötü bir kullanıcı deneyimine yol açar.
Tek bir HIDDevice
örneğinde forget()
çağrıldığında aynı fiziksel cihazdaki tüm HID arayüzlerine erişim iptal edilir.
// Voluntarily revoke access to this HID device.
await device.forget();
forget()
, Chrome 100 veya sonraki sürümlerde kullanılabildiğinden bu özelliğin aşağıdakilerle desteklenip desteklenmediğini kontrol edin:
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
Geliştiriciler için İpuçları
Chrome'da HID'yi hata ayıklamak, tüm HID ve USB cihazlarıyla ilgili etkinlikleri tek bir yerde görebileceğiniz about://device-log
dahili sayfasıyla kolaydır.

HID cihaz bilgilerini insanlar tarafından okunabilir bir biçime aktarmak için HID Explorer'ı inceleyin. Her HID kullanımı için kullanım değerlerinden adlara eşleme yapar.
Çoğu Linux sisteminde, HID cihazları varsayılan olarak salt okuma izinleriyle eşlenir. Chrome'un bir HID cihazı açmasına izin vermek için yeni bir udev
kuralı eklemeniz gerekir. /etc/udev/rules.d/50-yourdevicename.rules
konumunda aşağıdaki içeriğe sahip bir dosya oluşturun:
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Yukarıdaki satırda, cihazınız örneğin bir Nintendo Switch Joy-Con ise [yourdevicevendor]
, 057e
olur. Daha spesifik bir kural için ATTRS{idProduct}
da eklenebilir. user
hesabınızın plugdev
grubunun üyesi olduğundan emin olun. Ardından, cihazınızı yeniden bağlamanız yeterlidir.
Tarayıcı desteği
WebHID API, Chrome 89'da tüm masaüstü platformlarında (ChromeOS, Linux, macOS ve Windows) kullanılabilir.
Demolar
Bazı WebHID demoları web.dev/hid-examples adresinde listelenmiştir. Göz atmayı unutmayın.
Güvenlik ve gizlilik
Spesifikasyon yazarları, WebHID API'yi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme'de tanımlanan temel ilkeleri (kullanıcı kontrolü, şeffaflık ve ergonomi dahil) kullanarak tasarlayıp uygulamıştır. Bu API'yi kullanma özelliği, temel olarak aynı anda yalnızca tek bir HID cihazına erişim izni veren bir izin modeliyle sınırlıdır. Kullanıcı istemine yanıt olarak kullanıcının belirli bir HID cihazı seçmek için aktif adımlar atması gerekir.
Güvenlik açısından avantaj ve dezavantajları anlamak için WebHID spesifikasyonunun Güvenlik ve Gizlilikle İlgili Hususlar bölümüne göz atın.
Bunun yanı sıra Chrome, her üst düzey koleksiyonun kullanımını inceler.Üst düzey bir koleksiyonun korumalı kullanımı varsa (ör. genel klavye, fare), web sitesi bu koleksiyonda tanımlanan raporları gönderemez ve alamaz. Koruma altındaki kullanımların tam listesi herkese açıktır.
Güvenlik açısından hassas HID cihazlarının (ör. daha güçlü kimlik doğrulama için kullanılan FIDO HID cihazları) Chrome'da da engellendiğini unutmayın. USB engellenenler listesi ve HID engellenenler listesi dosyalarına bakın.
Geri bildirim
Chrome ekibi, WebHID API ile ilgili düşüncelerinizi ve deneyimlerinizi öğrenmekten memnuniyet duyar.
API tasarımı hakkında bilgi verin.
API ile ilgili beklendiği gibi çalışmayan bir durum var mı? Yoksa fikrinizi uygulamak için eksik yöntemler veya özellikler mi var?
WebHID API GitHub deposunda bir spesifikasyon sorunu bildirin veya düşüncelerinizi mevcut bir soruna ekleyin.
Uygulamayla ilgili sorun bildirme
Chrome'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?
WebHID hatalarını bildirme başlıklı makaleye göz atın. Mümkün olduğunca fazla ayrıntı eklediğinizden, hatayı yeniden oluşturmak için basit talimatlar verdiğinizden ve Bileşenler'in Blink>HID
olarak ayarlandığından emin olun.
Desteğinizi gösterme
WebHID API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı satıcılarına bu özelliklerin desteklenmesinin ne kadar önemli olduğunu gösterir.
@ChromiumDev'e #WebHID
hashtag'ini kullanarak tweet gönderin ve nerede, nasıl kullandığınızı bize bildirin.
Faydalı bağlantılar
- Spesifikasyon
- İzleme hatası
- ChromeStatus.com girişi
- Blink Bileşeni:
Blink>HID
Teşekkür
Bu makaleyi inceledikleri için Matt Reynolds ve Joe Medley'e teşekkür ederiz. Sara Kurfeß'in Unsplash'teki kırmızı ve mavi Nintendo Switch fotoğrafı ile Athul Cyriac Ajay'ın Unsplash'teki siyah ve gümüş renkli dizüstü bilgisayar fotoğrafı.