如何将CGI文件输出传递到index.html?树莓派LED状态显示问题
网页显示LED当前状态的几种解决方法
方法1:AJAX异步动态获取状态
这是最灵活的方式,不用刷新整个页面就能实时更新LED状态:
- 编写状态查询CGI脚本(命名为
get_led_status.cgi,放到cgi-bin目录),脚本要输出标准HTTP头,然后返回LED状态:
#!/bin/bash # 输出HTTP内容类型头 echo "Content-type: text/plain" echo "" # 读取3个LED的GPIO状态,替换成你的实际引脚号 led1=$(gpio -g read 18) led2=$(gpio -g read 23) led3=$(gpio -g read 24) # 用逗号分隔输出三个状态 echo "$led1,$led2,$led3"
给脚本加执行权限:sudo chmod +x /usr/lib/cgi-bin/get_led_status.cgi
- 修改index.html,添加JS代码定时拉取状态:
<!DOCTYPE html> <html> <head> <title>LED控制器</title> <script> // 每1秒刷新一次状态 setInterval(() => { const xhr = new XMLHttpRequest(); xhr.onload = function() { if (this.status === 200) { const [s1, s2, s3] = this.responseText.split(','); // 更新页面上的状态显示 document.getElementById('led1').textContent = s1 == 1 ? '✅ 开启' : '❌ 关闭'; document.getElementById('led2').textContent = s2 == 1 ? '✅ 开启' : '❌ 关闭'; document.getElementById('led3').textContent = s3 == 1 ? '✅ 开启' : '❌ 关闭'; } }; xhr.open('GET', '/cgi-bin/get_led_status.cgi', true); xhr.send(); }, 1000); </script> </head> <body> <!-- LED控制按钮 --> <div> <button onclick="location.href='/cgi-bin/led1_on.cgi'">LED1 开</button> <button onclick="location.href='/cgi-bin/led1_off.cgi'">LED1 关</button> <span id="led1">加载中...</span> </div> <div> <button onclick="location.href='/cgi-bin/led2_on.cgi'">LED2 开</button> <button onclick="location.href='/cgi-bin/led2_off.cgi'">LED2 关</button> <span id="led2">加载中...</span> </div> <div> <button onclick="location.href='/cgi-bin/led3_on.cgi'">LED3 开</button> <button onclick="location.href='/cgi-bin/led3_off.cgi'">LED3 关</button> <span id="led3">加载中...</span> </div> </body> </html>
方法2:让控制CGI直接返回带状态的页面
如果接受页面跳转刷新,可以修改你的LED控制CGI,执行开关操作后直接生成包含状态的HTML页面:
比如修改led1_on.cgi:
#!/bin/bash echo "Content-type: text/html" echo "" # 执行开启LED1的操作 gpio -g write 18 1 # 查询所有LED当前状态 led1=$(gpio -g read 18) led2=$(gpio -g read 23) led3=$(gpio -g read 24) # 输出完整HTML页面 cat << EOF <!DOCTYPE html> <html> <head> <title>LED状态</title> </head> <body> <h2>LED1已开启</h2> <p>当前各LED状态:</p> <ul> <li>LED1: $( [ $led1 -eq 1 ] && echo '开启' || echo '关闭' )</li> <li>LED2: $( [ $led2 -eq 1 ] && echo '开启' || echo '关闭' )</li> <li>LED3: $( [ $led3 -eq 1 ] && echo '开启' || echo '关闭' )</li> </ul> <p><a href="/index.html">回到控制页面</a></p> </body> </html> EOF
方法3:用服务器端包含(SSI)嵌入状态
如果你的Web服务器是Apache,开启SSI后可以直接在HTML里嵌入CGI输出:
- 开启Apache的SSI模块:
sudo a2enmod include sudo systemctl restart apache2
编辑Apache的站点配置(比如/etc/apache2/sites-available/000-default.conf),在/var/www/html目录块里加上Includes:
<Directory /var/www/html> Options Indexes FollowSymLinks Includes AllowOverride None Require all granted </Directory>
重启Apache:sudo systemctl restart apache2
- 把index.html改名为index.shtml,然后在需要显示状态的地方插入SSI指令:
<!DOCTYPE html> <html> <head> <title>LED控制器</title> </head> <body> <div> <button onclick="location.href='/cgi-bin/led1_on.cgi'">LED1 开</button> <button onclick="location.href='/cgi-bin/led1_off.cgi'">LED1 关</button> <!-- 嵌入CGI输出的LED1状态 --> <span>状态:<!--#include virtual="/cgi-bin/get_led1_status.cgi" --></span> </div> <!-- 其他LED同理 --> </body> </html>
这里的get_led1_status.cgi要输出直接可读的状态文本,比如:
#!/bin/bash echo "Content-type: text/plain" echo "" status=$(gpio -g read 18) [ $status -eq 1 ] && echo "开启" || echo "关闭"
内容的提问来源于stack exchange,提问作者user21497260
相关产品推荐
相关产品推荐

