You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MicroPython的ESP8266 Captive Portal无法自动重定向问题

解决ESP8266 Captive Portal自动重定向失效问题

你的问题核心是:当前代码只处理了普通HTTP请求,但手机、电脑这类设备连接AP后,会发送特定的系统探测请求来判断是否需要强制门户,你的代码没拦截这些请求,所以不会自动触发重定向。另外原代码的响应逻辑混乱,重复发送响应会导致设备无法正确解析。

核心修复步骤

  • 拦截主流设备的探测URL:苹果的/hotspot-detect.html、安卓的/generate_204、Windows的/ncsi.txt,还有根路径/
  • 修复请求解析逻辑:从ESP8266的+IPD响应中提取正确的连接ID和请求URL,别固定用0
  • 简化响应流程:直接返回门户页面,避免不必要的多次重定向和连接关闭操作

修复后的完整代码

from machine import UART, Pin
import time

uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1))  

def send_command(command, delay=0.5):
    uart.write(command + '\r\n')
    time.sleep(delay)
    response = uart.read()
    if response:
        print(response.decode('utf-8'))
    return response

def setup_wifi_ap():
    print("配置ESP8266...")
    send_command("AT+RST", 2) 
    send_command("AT+CWMODE=2")
    send_command('AT+CWSAP="Test","",5,0')
    send_command("AT+CIPMUX=1")  
    send_command("AT+CIPSERVER=1,80")
    print("无密码AP配置完成!")

def parse_request(response_str):
    # 从+IPD响应里提取请求的URL和连接ID
    if "+IPD" in response_str:
        # 示例格式:+IPD,0,123:GET /hotspot-detect.html HTTP/1.1\r\n...
        request_part = response_str.split(':')[1]
        url = request_part.split(' ')[1]
        conn_id = response_str.split(',')[1]
        return url, conn_id
    return None, None

def handle_requests():
    print("HTTP服务器运行中...")
    while True:
        response = uart.read()
        if response:
            response_str = response.decode('utf-8')
            print(response_str)
            url, conn_id = parse_request(response_str)
            if url:
                # 需要拦截的探测URL列表
                captive_triggers = ['/hotspot-detect.html', '/generate_204', '/ncsi.txt', '/']
                if url in captive_triggers or url.startswith('/'):
                    # 直接返回门户页面,也可以换成302重定向
                    html_content = """HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n
                    <html><body><h1>欢迎!</h1><p>请完成设置以访问互联网。</p></body></html>"""
                    # 去掉多余缩进,避免长度计算错误
                    clean_html = html_content.replace('\n                    ', '')
                    # 发送响应
                    send_command(f'AT+CIPSEND={conn_id},{len(clean_html)}')
                    uart.write(clean_html)
                    time.sleep(0.2)
                    send_command(f'AT+CIPCLOSE={conn_id}')

# 初始化运行
setup_wifi_ap()
handle_requests()

关键点说明

  1. 探测URL拦截:覆盖了所有主流系统的探测请求,设备连接后会自动触发门户加载
  2. 动态连接ID:不再固定用0,多设备同时连接时也能正常处理
  3. 长度计算准确:移除HTML里的多余缩进,避免ESP8266因为长度不匹配拒绝发送
  4. 简化响应:直接返回200页面,比302重定向更可靠,减少设备解析出错的概率

内容的提问来源于stack exchange,提问作者Look_thisSTREAMING

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:25:19