Web Bluetooth连接ESP32报错:NotSupportedError: GATT操作不允许
解决Web Bluetooth API调用
characteristic.writeValue()时的"NotSupportedError: GATT operation not permitted"错误 可能原因及解决方案:
检查特征值的写权限配置
先确认ESP32端定义的目标特征值(UUID:10001111-0000-1000-8000-00805f9b34fb)是否开启了WRITE或WRITE_WITHOUT_RESPONSE属性。可以通过nRF Connect查看特征值的属性标识,必须包含写权限才能正常调用writeValue。
对应ESP32代码中,添加特征值时要明确指定权限,比如:pCharacteristic = pService->createCharacteristic( UUID("10001111-0000-1000-8000-00805f9b34fb"), BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ );修正代码中的连接状态判断逻辑
你代码里用bluetoothDevice.connected做判断,但bluetoothDevice被赋值为device.gatt,这个判断逻辑存在误差。Promise链式调用本身会处理前一步的失败,不需要额外判断连接状态,去掉多余的if分支即可,避免阻断正常流程。避免写入后立即断开连接
原代码在writeValue后立刻调用disconnect(),可能导致GATT写入操作还未完成就中断,引发权限错误。可以添加短暂延迟后再断开,确保写入操作执行完毕。确认写入数据格式合规
writeValue接受ArrayBuffer、TypedArray或DataView类型参数,你用Uint8Array是没问题的,但要确保数据长度不超过ESP32端特征值定义的最大长度。
修正后的代码示例:
$(document).ready(function(){ let bluetoothDevice = null; let requestDeviceParams = { filters: [ {name: ["konko"]} ], optionalServices: ['10001001-0000-1000-8000-00805f9b34fb'] } let dateInput = document.querySelector('#date-input') $("#synch-date-time").click(() => { if (dateInput.value === '') { console.error('日期字段为空,请填写'); return; } asyncResultNotif(); }) async function asyncResultNotif(){ try { const device = await navigator.bluetooth.requestDevice(requestDeviceParams); bluetoothDevice = device; const server = await device.gatt.connect(); const service = await server.getPrimaryService('10001001-0000-1000-8000-00805f9b34fb'); const characteristic = await service.getCharacteristic('10001111-0000-1000-8000-00805f9b34fb'); // 构造并发送数据 let data = `{"ssid": "${dateInput.value}"}`; console.log(data); let encoder = new TextEncoder('utf-8'); let val = encoder.encode(data); await characteristic.writeValue(val); // 延迟断开,确保写入完成 setTimeout(() => { if (bluetoothDevice.gatt.connected) { bluetoothDevice.gatt.disconnect(); console.log('设备已断开'); } }, 500); } catch (error) { console.error('错误: ' + error); } } });
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

