移动端浏览器访问ESP32 HTTP REST API时遭遇混合内容限制的解决方案咨询
我最近做了一个基于ESP32的Arduino项目——发光南瓜(Glowing Pumpkin),用了一组NeoPixel LED灯,它能随机切换颜色、模拟闪电效果,专门放在雕刻好的南瓜里使用。
后来我给这个项目扩展了功能:在ESP32的其中一个核心上跑了个Web服务器(主要是想学习怎么在Arduino项目里实现多核运行代码)。
这个REST API在桌面Chrome浏览器里配合CORS配置运行得不错,但因为Chrome对HTTP端点的安全限制,我必须在网站设置里给我的Web应用「Pumpkin Controller」开启「不安全内容」权限才能正常使用。下面是我写的前端请求代码:
const headers = new Headers(); headers.append('Accept', 'application/json'); headers.append('Access-Control-Allow-Origin', '*'); headers.append('Access-Control-Allow-Headers', '*'); const fetchOptions = { mode: "cors", headers }; async function execCmd(cmdStr) { var ipAddress = localStorage.getItem(hostAddressKey); if (ipAddress == null || ipAddress == "") { console.error('Missing IP Address'); return; } let theURL = `http://${ipAddress}/${cmdStr}`; try { const response = await fetch(theURL, fetchOptions); response.json() .then(json => { if (response.status == 200) { Swal.fire({ text: 'Successfully executed command', toast: true, timer: 1500, position: 'top', icon: successIcon }); } else { console.log(`HTTP error: ${response.status}`); } }); } catch (err) { console.dir(err); } }
在桌面端开启「不安全内容」后,虽然控制台会弹出警告,但功能还能正常工作:
Click: btnRandom
index.js:79 Executing: http://192.168.86.230/random
index.js:82 Mixed Content: The page at 'https://pumpkin-controller.netlify.app/' was loaded over HTTPS, but requested an insecure resource 'http://192.168.86.230/random'. This content should also be served over HTTPS.
execCmd @ index.js:82
(anonymous) @ index.js:48
但到了移动端就彻底卡住了——安卓版Chrome根本不允许在网站设置里开启「不安全内容」,请求直接被拦截,报错信息如下:
Click: btnOff
index.js:79 Executing: http://192.168.86.230/off
index.js:82 Mixed Content: The page at 'https://pumpkin-controller.netlify.app/' was loaded over HTTPS, but requested an insecure resource 'http://192.168.86.230/off'. This request has been blocked; the content must be served over HTTPS.
execCmd @ index.js:82
(anonymous) @ index.js:42
index.js:99 TypeError: Failed to fetch
at execCmd (https://pumpkin-controller.netlify.app/index.js:82:28)
at HTMLButtonElement.(https://pumpkin-controller.netlify.app/index.js:42:3)
index.js:100 Failed to fetch
现在我想请教几个问题:
- 有没有其他方法能让浏览器应用通过HTTP连接ESP32的REST API?有没有能绕过Chrome限制的HTTP库?
- 之前Copilot推荐我用XHR请求代替fetch,是不是XHR能解决这个混合内容的问题?
- 我知道给ESP32部署SSL证书能绕过这个限制,但这个操作太复杂了,我不想走这条路;另外我之前用Flutter做过安卓/iOS原生应用来连接ESP32,但没试过Flutter Web应用,这种方式可行吗?
备注:内容来源于stack exchange,提问作者johnwargo

