web midi api 在在线 html 工具中无法运行,因其要求安全上下文(https 或 localhost),而 jsfiddle、codepen 等沙盒 iframe 不满足条件;唯一可靠调试环境是本地 http://localhost:8080,需显式启用 sysex、手动处理权限及设备状态变更。

Web MIDI API 在在线 HTML 工具中根本跑不起来
直接告诉你结论:navigator.requestMIDIAccess() 在大多数在线 HTML 运行工具(如 JSFiddle、CodePen、JSBin、甚至部分 VS Code Live Server 本地预览)中会静默失败或返回 undefined,不是你代码写错了,是环境不满足前提条件。
原因很实在:Web MIDI API 要求页面必须运行在 安全上下文(secure context) 下——即 https:// 协议,或 localhost。而绝大多数在线编辑器的预览 iframe 是沙盒化的,协议为 about:blank 或非 localhost 的 http 域名,浏览器直接拒掉 MIDI 权限请求。
- CodePen 预览页地址类似
https://cdpn.io/pen.../fullpage/?看起来是 https,但 iframe 的sandbox属性默认禁用midi特性,且父页面无法授权子 frame 访问 MIDI - JSFiddle 的
/show/页面虽走 https,但实际执行环境被隔离,navigator.requestMIDIAccess返回Promise但 resolve 后inputs和outputs为空数组 - 即使你加了
features="midi"到 sandbox 属性,现代浏览器(Chrome ≥95、Edge ≥95)仍强制要求顶层文档显式启用,而在线工具不给你改这个权限的机会
能跑通 Web MIDI 的最小可行调试环境
别折腾在线工具了,本地起一个真正可控的环境,三步搞定:
- 把 HTML 文件保存为
index.html,内容包含基础 MIDI 请求逻辑(比如调用navigator.requestMIDIAccess({ sysex: true })) - 用命令行启动一个最简 HTTP 服务:
npx http-server -c-1(-c-1禁用缓存,避免 MIDI 设备列表不更新) - 浏览器打开
http://localhost:8080—— 这就是唯一靠谱的调试入口。注意:必须是localhost,不能是127.0.0.1(某些系统 MIDI 权限策略对后者更严格)
如果仍失败,检查控制台是否报错 DOMException: Requesting MIDI access is not allowed in this context,那说明你没在 localhost 或用了文件协议(file://),后者绝对不行。
调试时最容易忽略的两个设备级细节
MIDI 设备连接状态和权限弹窗时机,比代码逻辑更容易卡住调试流程:
- Chrome / Edge 在首次调用
navigator.requestMIDIAccess()时才会触发权限弹窗;但如果你之前点过“拒绝”,它不会再次出现,得手动进chrome://settings/content/midi清除站点权限 - USB MIDI 设备(比如 AKAI MPK Mini、Novation Launchkey)插拔后,
MIDIAccess实例不会自动刷新设备列表——你得重新调用requestMIDIAccess(),或监听statechange事件(需先拿到 access 实例):access.onstatechange = e => { console.log(e.port.name, e.port.state); }; -
sysex: true必须显式传入选项,否则即使设备支持 SysEx(如多数合成器),send()方法也会静默失败,且无错误提示
验证 MIDI 输入是否真在工作:用最简回声逻辑
别一上来就做音符转音频,先确认输入通路畅通。以下代码可直接贴进本地 index.html,打开控制台看输出:
navigator.requestMIDIAccess({ sysex: true })
.then(access => {
access.inputs.forEach(input => {
input.onmidimessage = e => {
console.log('MIDI IN:', e.data[0].toString(16), e.data[1], e.data[2]);
};
});
})
.catch(err => console.error('MIDI init failed:', err));
敲击键盘或推旋钮时,如果看到类似 MIDI IN: 90 60 127(Note On)或 B0 7 127(CC#7),说明链路已通。注意:e.data 是 Uint8Array,不要用 e.data.toString() 直接打,会输出逗号分隔字符串而非十六进制值。
真正的难点不在 API 调用,而在浏览器安全模型、设备驱动状态、以及那个只出现一次的权限弹窗——错过它,后面所有逻辑都是空转。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











