Разрешения Web Serial и жизненный цикл порта
Запрашивайте Web Serial действием пользователя, отделяйте разрешение от готовности порта, ограничивайте потоки и сохраняйте запасной путь.
BotBrowser Team
Нужна структурированная документация по теме Платформа?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Web Serial позволяет запросить выбранный пользователем последовательный порт, но результат селектора не доказывает соединение, доверие или владение. BotBrowser может проверить ветки разрешения и запасного пути страницы в управляемом контексте; он не предоставляет физическое устройство, не выдаёт системное разрешение и не доказывает аппаратный ввод-вывод. Запрашивайте после действия, открывайте поддержанный порт, ограничивайте кадры, отменяйте потоки при отключении и сохраняйте задачу без оборудования.
TL;DR
navigator.serial.requestPort({ filters: [{ usbVendorId: 0x2341 }] })требует защищённый контекст и краткую активацию пользователя.- Выбранный
SerialPortявляется возможностью источника, но не доказывает, что порт открыт, подключён или совместим. - Открывайте
port.open({ baudRate: 115200 })с проверенной конфигурацией и валидируйте каждый кадр. - События
connectиdisconnectпоказывают наблюдение браузера; отменяйте readers, освобождайте locks и закрывайте порт. - Храните
granted,unsupported,invalid-frameилиdisconnected, а не серийные номера и сырые буферы.
Содержание
- Запрашивайте в момент использования
- Отделяйте разрешение от готовности
- Ограничивайте потоки
- Согласуйте connect и disconnect
- Минимизируйте метаданные и сохраняйте запасной путь
- Классифицируйте результаты
- Возможность и ограничение BotBrowser
- Итог
Запрашивайте в момент использования
Web Serial работает только в защищённых контекстах, а requestPort() должен следовать действию. Наличие navigator.serial не открывает селектор. Политика iframe, настройка браузера, платформа или ОС могут отклонить запрос.
async function connectSerial() {
if (!window.isSecureContext || !navigator.serial) return showSerialState('unsupported');
setSerialState('requesting');
try {
const port = await navigator.serial.requestPort({
filters: [{ usbVendorId: 0x2341 }],
});
await openSelectedPort(port);
} catch (error) {
showSerialState(error.name === 'NotFoundError' ? 'cancelled' : 'denied');
}
}
connectButton.addEventListener('click', connectSerial);
Не открывайте селектор при загрузке и не повторяйте запрос после отмены. Сохраните черновик. Доступ WebUSB: разрешения, интерфейсы и приватность разделяет разрешение и готовность; Разрешения WebHID и приватность устройств рассматривает жизненный цикл HID-отчётов; Отпечаток разрешений браузера объясняет, почему состояние не выдаёт доступ и не определяет человека.
Отделяйте разрешение от готовности
requestPort() возвращает выбранный порт, но он может быть отключён, иметь неверный baudRate или другой протокол. Считайте выбор, открытие, чтение, запись и закрытие отдельными состояниями. Документируйте baudRate, dataBits, stopBits, parity и flowControl, а проверку протокола выполняйте после декодера.
navigator.serial.getPorts() не является полным инвентарём. Повторное подключение должно быть явным и снова проверять конфигурацию. Спецификация Web Serial и MDN Web Serial API описывают интерфейс, но не доказывают личность, место или физический результат.
Ограничивайте потоки
port.readable и port.writable являются асинхронными потоками. Используйте максимум размера, разделитель или длину, checksum при наличии в протоколе и тайм-аут неполного кадра.
const MAX_FRAME_BYTES = 128;
async function readSerialFrames(port) {
const reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
if (value.byteLength > MAX_FRAME_BYTES) {
showSerialState('invalid-frame');
continue;
}
acceptBoundedFrame(value);
}
} finally {
reader.releaseLock();
}
}
Не записывайте каждый байт и не передавайте произвольный кадр интерпретатору. Классифицируйте invalid-length, invalid-checksum и timeout. Успешный writer.write() означает только принятие браузером, а не движение устройства. Освобождайте writer и отменяйте reader до close().
Согласуйте connect и disconnect
connect показывает появление порта, а disconnect означает наблюдаемое удаление. Они не объясняют причину и не разрешают тихий запрос. При отключении сделайте задачу терминальной, отмените reader, освободите writer, вызовите port.close() с обработкой ошибки, удалите listeners, сохраните данные и покажите кнопку переподключения. Не отправляйте последнюю команду автоматически.
Используйте idle, requesting, selected, opening, opened, reading, invalid-frame, disconnected, cancelled и fallback. При возврате портов повторяйте конфигурацию и handshake; serialNumber и getInfo() не являются личностью.
Минимизируйте метаданные и сохраняйте запасной путь
Разделяйте разрешение, сессию, согласие протокола и удалённую загрузку. Локальное чтение не разрешает передачу. В журнале достаточно unsupported, denied, cancelled, opened, invalid-frame, disconnected или fallback, времени и окружения. Не храните getInfo(), USB-идентификаторы, буферы и длинную историю. Оставьте ручной ввод, импорт, симулированное значение или статическую конфигурацию.
Классифицируйте результаты
| Стадия | Что установлено | Безопасное действие |
|---|---|---|
| API отсутствует, контекст небезопасен или политика | Web Serial не запускается | Сохранить задачу без порта |
| Селектор отменён или разрешение отклонено | Нет доступа для попытки | Сохранить черновик |
open() отклонён | Сессия непригодна | Показать настройки и закрыть |
| Неверный кадр | Протокол отклонил вход | Отбросить и классифицировать |
disconnect | Браузер наблюдал удаление | Отменить, закрыть, сохранить и предложить повтор |
| Валидный кадр | Принято одно значение | Не выводить физический эффект |
Возможность и ограничение BotBrowser
BotBrowser может проверить кнопку, обнаружение, результат селектора, ограниченную валидацию, очистку отключения и запасной путь. Документация расширенных возможностей описывает такой контекст. Он не предоставляет периферийное устройство, системное разрешение, гарантированный порт или доказательство аппаратного эффекта. BotBrowser проверяет видимые состояния navigator.serial и запасной путь, но не подтверждает работу реального электрического устройства.
const serialOutcome = { state: 'fallback', rawIdentifiersRetained: false };
showSerialState(serialOutcome.state);
{
"api": "navigator.serial",
"permission": "denied",
"portState": "fallback",
"framesAccepted": 0,
"rawIdentifiersRetained": false,
"physicalDevice": "not-asserted"
}
Источники
Итог
Используйте явное действие, разделяйте разрешение, открытие и потоки, проверяйте каждый кадр и отменяйте readers перед закрытием. Сохраняйте задачу без оборудования и записывайте стадию ошибки вместо метаданных. Повторяйте fixture после обновления; успех страницы не обещает физического поведения.
Эта статья входит в руководство: Поверхности веб-платформы: карта проверки
Похожие статьи
Разрешение WebHID и границы приватности устройства
ПлатформаWeb MIDI API: разрешения и приватность устройств
ИдентичностьДоступ к устройствам WebUSB: разрешения, интерфейсы и приватность
ПлатформаWeb Share API: границы разрешений и безопасные запасные варианты
ПлатформаWindow Management API: границы нескольких экранов
ПлатформаPresentation API: границы экрана и сессии
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.